-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Description
Version
2.5.7
Reproduction link
https://jsfiddle.net/elijahww/oct9s9pa/
Steps to reproduce
I was having difficulties in my app getting a "computed" to notice that my array was altered (deeply). The array was modified via arr.push({val:'hello'})
. That part gets noticed. But changes to the data I push does not get detected, arr[1].val = 'bye'
does not get detected... unless:
I played around with different ways to tell Vue what to look for in 'computed' and I did find a condition that solves my scenario, but a) I don't understand why it works, b) it's not straight forward.
Basically, I iterate through the array in computed function and touch every getter. That seems to satisfy the Dep tracking logic. Notice, however, in my example that array starts off with 0 elements, and I am looping on a zero element array, and yet it works. Why?
If you remove line 7: (this.arr[i].val;)
, my change detection no longer works. Who knows what V8 does to the rest of the for-loop. Maybe it yanks it out at runtime?
What I would like is an API to add something to the computed Dep tracker. In my example, when I add a new element to array, I could call something like this.$updateComputed('myComputedName').
var track = 0; // track iGotEvaluated calls
Vue.component('comp', {
computed: {
iGotEvaluated: function() {
for (var i = 0; i < this.arr.length; i ) {
this.arr[i].val;
}
return track;
}
},
template: `
<div>
<div>computed: #{{ iGotEvaluated }}</div>
<div v-for="n in arr">
<input v-model="n.val"/>
</div>
<button v-on:click="add()">Add</button>
</div>`,
data: function() {
return {
arr: []
}
},
methods: {
add: function() {
this.arr.push({val: 'edit me'});
}
}
})
new Vue({el: '#app'})
What is expected?
A more straight forward way to determine when change in deep array will trigger computed
What is actually happening?
When dealing with deep array object it is not clear when the change detection will take place