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 input
s (green):
Vue tools showing items:
.
Remove item:
Middle item removed - and data gone from the last item (the remove button shows the loop index):
Vue tools showing the removed item and :key
still the same for last item (...diaries.3.sub...) client_details.subsidiaries.3.subsidiary_company_name
:
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">