I have an array of the following structure:
[
{
start: "str",
end: "str",
},
...
]
and template similar to:
<templateList v-for="(item, index) in itemList" :key="'item-'+index">
<templateItem v-bind="item" />
</templateList>
Template item is just a template that has 2 fields for the user to entre values for start and end. Everything here is reactive and working great. Since there is no persistent value, we used item-$index
as a key, although understandably not the greatest.
This list can be dynamically extended and shrunk. To delete an entry, I’m currently doing
this.itemList.splice(index, 1)
The issue is when I have more than 2 items and I try to delete an item in the middle. Consider the following example:
[
{
start: "start1",
end: "end1",
},
{
start: "start2",
end: "end2",
},
{
start: "start3",
end: "end3",
},
]
When the UI element is triggered and causes this splice:
this.itemList.splice(1, 1); // removing the middle element, with "start2" and "end2"
After the list has been changed, the UI does remove one element. However, it renders the values incorrectly, and renders as if the array has this value:
[
{
start: "start1",
end: "end1",
},
{
start: "start2",
end: "end2",
},
]
Debugging logging shows the array to have this (correct) value:
[
{
start: "start1",
end: "end1",
},
{ // as expected
start: "start3",
end: "end3",
},
I’m not too sure if the key is the issue here, as Vue correctly reacted to the shortening of the array and removed an element, but it doesn’t seem to think the actual values have changed – so maybe it thought item-2
disappeared, and didn’t bother re-rendering item-1
.
Any help is appreciated, and unfortunately I do not have any immutable fields in these objects. Adding an extra field would be quite complex in the data export after due to how the project is structured, so a solution before using a hash / UUID in each element would be appreciated if possible. Thanks!
<templateList v-for="(item, index) in itemList" :key="item.start">
<templateItem v-bind="item" />
</templateList>
The ‘key’ must be unique.
This is caused by Vue’s “reuse in place” strategy.