Home > Back-end >  VueJs: Removing item from middle of array re-renders all subsequent items
VueJs: Removing item from middle of array re-renders all subsequent items

Time:06-20

I have an array of objects which are looped over in a Vue template, each contains <input>s. User’s have a button to add additional items to the array - these are rendered - that all works perfectly. Each new component is given a unique key.

Users are able to remove any of the added <input>s using a button. This works correctly in the data.repeats array - the item is removed. The DOM is also updated to remove this item.

However, if I have 4 items and remove the second, items 3 and 4 will be re-rendered (I can see they were ‘updated’ in in Vue dev tools). This will loose any data added to those inputs (or changes to DOM etc.).

It’s only items after the removed one that this happens to.

From my understanding, by using :key on the component Vue should be able to track it and re-render.

I thought it might be because I was storing the items in an array and when removing one in the centre all the keys after decremented by one so I tried using an object with named properties which never change but the result in the DOM is the same - all items after the removed one get re-rendered.

Is there way to stop this?

<div v-for="(repeat, count) in repeats">
    <template v-for="field in repeat">
        <component
            :is="field.component" 
            :content="field.content"
            :key="field.content.dot_name"
        >
        </component>
    </template>

    <button @click="remove(count)">Remove</button>
</div>

<button @click="add">Add</button>
data() {
    return {
        repeats: []
    }
},

methods: {
    add() {
        this.repeats.push(this.cloneFields());
    },
    remove(key) {
        this.repeats.splice(key, 1);
    },
}

Added items:

Three items added with data in inputs (green):

enter image description here

Vue tools showing items:

enter image description here

.

Remove item:

Middle item removed - and data gone from the last item (the remove button shows the loop index):

enter image description here

Vue tools showing the removed item and :key still the same for last item (...diaries.3.sub...) client_details.subsidiaries.3.subsidiary_company_name:

enter image description here

CodePudding user response:

Try adding a key to v-for="(repeat, count) in repeats" loop

CodePudding user response:

As per your code count represent index so make different key for both loops

like add key (avoid a non-primitive key instead of that use string or number) to the outer loop

<div v-for="(repeat, count) in repeats" :key="'outer'   count">

and for the inner loop

 <template v-for="(field, index) in repeat" :key="'inner'   index">
  • Related