2

In this area, I want to enter people's name and surname. This is my small component.

<v-row v-for="(list,i) in getList" :key="'list-item-'+i">
    
    <v-col cols="6"><v-text-field v-model="name"/></v-col>

    <v-col cols="6" > <v-text-field v-model="surName"/></v-col>

</v-row> 
data(){
    return{
          name:nulll,
          surName:null
       }
},

computed: {
        getList() {
            const newCategory = []

            const getCategory= [
                {category: 'elder', count: 3},
                {category: 'babies', count: 1},
                {category: 'children', count: 0}
            ]

            getCategory.map(item => {
                return item.count > 0 ? newCategory .push(item) : null
            })

            return newCategory 
        }
    },

The getList is an array and I filtered it if the count is not bigger than 0. My problem is about creating the right component counts for every object. For example, there are 3 elders and 1 baby in my getList array. So ı need to create 4 component forms for this.

But in my solution I can obtain only 2 components. 1 elder and 1 baby. Sure I need to create 4 components. 3 elders and 1 baby.

2
  • In your case, the binding is always the same for all of the ones in the array. ( if you change one of those, it will change all of the fields ) Are you really expecting such a behaviour? Commented Jan 30, 2021 at 14:48
  • I saw my mistake in here . I think i must find a way for this Commented Jan 30, 2021 at 15:30

1 Answer 1

1

Array.map maps one array to another. If you start off with 3 elements as is in your case, you end up with 3 elements in the final array. How you solve that problem depends mostly on how you eventually solve the problem that you are currently mapping all name fields to the same name variable in your component.

You could use an Array.reduce, which also loops through all elements of the original array, but gives you much more freedom in what you output.

const categories = [
  {category: 'elder', count: 3},
  {category: 'babies', count: 1},
  {category: 'children', count: 0}
]

const formRows = categories.reduce(
  (accumulator, item) => {
    for (let i = 0; i < item.count; i++) {
      accumulator.push({
        category: item.category,
        name: '',
        surName: ''
      });
    }

    return accumulator;
  },
  []
);

// Here we have an array with 4 items, 3 with category elder and one with category babies

Another way of solving this problem is to loop in the template itself

<template v-for="list in getList">
  <template v-if="list">
    <template v-for="i in list.count">
      <v-row :key="i">
        <!-- Note, these models all refer to the same variable, so they change at the same time... -->
        <v-col cols="6"><v-text-field v-model="name"/></v-col>
        <v-col cols="6"><v-text-field v-model="surName"/></v-col>
      </v-row> 
    </template>
  </template>
</template>
Sign up to request clarification or add additional context in comments.

3 Comments

Second solution looks clear but i don't know if it causes performance losing.
The first and seconds solution should be similar in performance. Also keep in mind that we are talking about 8 input fields, not 100's of them, so performance is unlikely to be an issue for some time. Also keep in mind that you first need to think about how to map the v-model of each of these fields to their own variable and choose your solution based on that.
Yes ı realized i must change v-model working logic in here otherwise i can't keep names and surnames . In my solution , i get only last entered name and surname

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.