My curiosity is piqued by a puzzling issue with updating specific items in an array using Vue.js. The documentation cautions that:
Due to limitations in JavaScript, Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g.
vm.items[indexOfItem] = newValue
.
While this guideline is clear, I am left wondering about the reasoning behind it. A similar query was raised in another discussion (Vue computed issue - when will it compute again).
The code snippet from the aforementioned question is as follows:
// works well
data() {
return {
cart: {
item: {
nums: 10,
price: 10,
},
},
}
},
computed: {
total() {
return this.cart.item.nums * this.cart.item.price
},
},
methods: {
set() {
//why it worked.
this.cart.item = {
nums: 5,
price: 5,
}
},
},
// oops! not working!
data() {
return {
cart: [
{
nums: 10,
price: 10,
},
],
}
},
computed: {
total() {
return this.cart[0].nums * this.cart[0].price
},
},
methods: {
set() {
this.cart[0] = {
nums: 5,
price: 5,
}
},
},
The explanation provided in response to the question is intriguing:
total will be recalculated if
this.cart
is marked as changed,this.cart[0]
is marked as changed or ifthis.cart[0].nums
orthis.cart[0].price
is changed. The problem is that you are replacing the object inthis.cart[0]
. This means thatthis.cart[0].price
and nums do not change, because those still point to the old object.
If I have replaced the object in this.cart[0]
, why isn't this.cart[0]
marked as changed? Why do this.cart[0].price
and nums
still point to the old object? I definitely made changes to this.cart[0], right?
Furthermore, what sets apart the two scenarios considering that both involve object replacement? Why does one work while the other doesn't?