Reputation: 2136
I have an array of elements that I supply for a vue component as a reactive data source (I'm inspecting the data with the vue chrome extension):
the view: [A,B,C,D,E]
the data: [A,B,C,D,E]
I want to move an item (D) to a new position (before B), so first I remove the element with splice
, then reinsert it at the desired index:
the view: [A,D,B,C,E]
the data: [A,B,C,D,E]
So when I hover over in the Chrome Vue inspector over the second component, in the view the third column gets highlighted. If I hover over the 3rd element in the data, in the view the 4th element get highlighted, and so on.
The view updates correctly, but I want underlying the data to follow it. In the array the elements are objects.
I guess this is because they are passed as reference?
Upvotes: 3
Views: 2150
Reputation: 2136
I think I've found it, instead of splice I should use set
and remove
on the vue instance:
https://v2.vuejs.org/v2/api/#Vue-set
You should avoid directly setting elements of a data-bound Array with indices, because those changes will not be picked up by Vue.js. Instead, use the augmented $set() method
Upvotes: 1
Reputation: 4170
I had the same issue as well, what happened was I didn't use unique key
values for each vue object in the array. I used the index in the array as the key. So when items were resorted, some of the data would be binded to different items because keys were swapped.
What I used was a Date.now()
function to initialize a UUID to set for each key
So for instance, say we had the key set to the index of the array
[ 0, 1, 2, 3, 4] - The keys
[A0,B0,C0,D0,E0] - The array of objects
[A1,B1,C1,D1,E1] - The data attribute inside each of the objects in array
So [A0] has a key of [0], and data attribute of [A1]. Say we swap [A0] and [B0]
[ 0, 1, 2, 3, 4] - the key
[B0,A0,C0,D0,E0] - the array of objects
[A1,B1,C1,D1,E1] - the data attribute assigned to each object in array
Now [A0] is binded to the data attribute of [B1], because [B1] is binded to the key of [1] and A[0] key is [1]
This is never what you want, so you want to make each key unique instead. A common way of doing this is using a Date.now()
method upon data initialization, or a create a UUID
Example in Vue for creating a unique UUID for each object when using vue methods
methods: {
_addGroup: function() {
let result = {
sortId: this.wizardGroups.length + 1,
text: 'Hello world'
uuid: Date.now(),
};
this.wizardGroups.push(result);
}
Assign that value to the key during v-for
iteration
<child-component
v-for="wizardGroup in wizardGroups"
:key="wizardGroup.uuid">
</child-component>
Upvotes: 0