Reputation: 195
Multilayer nested about Vue data like this:
out:{
arr:[
{a:1}
]
}
When I change the value using this.out.arr[0] = {a:2}
, the view is not updated. But if my code is this.out.arr[0].a = 2;
, the view is updated.
Here's a link!
You can comment and uncomment code in the method changeA
to see the different results!
Upvotes: 2
Views: 273
Reputation: 29092
I believe this is just the standard caveat around updating arrays via indices:
https://v2.vuejs.org/v2/guide/list.html#Caveats
Vue can't detect changes made to an array by directly assigning a value to an index.
So instead of this:
this.out.arr[0] = {a:2}
... you'd need to use this:
this.$set(this.out.arr, 0, {a: 2})
Update:
To understand the difference between the two cases mentioned in the question it might help to write them out in full.
this.out.arr[0] = {a:2}
// ... is equivalent to ...
const arr = this.out.arr // read
arr[0] = {a: 2} // write
Whereas:
this.out.arr[0].a = 2
// ... is equivalent to ...
const obj = this.out.arr[0] // read
obj.a = 2 // write
In the two examples above I've split up the read and write parts of the expressions. Reading values using an array index isn't a problem, just writing. The first example tries to write the 0
property of arr
, which violates the Vue indices caveat. The second example tries to write to the a
property of obj
, which doesn't feature an array index so has no such problem.
Upvotes: 1
Reputation: 222
Above @skirtle answer is the correct way to update vue data ! In vue documentation , it said
For example, when you set vm.someData = 'new value', the component will not re-render immediately. It will update in the next “tick”, when the queue is flushed.
So , setting directly by index will not update dom immediately .... you need to do forceUpdate
this.out.arr[0] = {a:2}; // can not updated
this.$nextTick(function () {
this.$forceUpdate(); // will be update
});
Upvotes: 0