I have this Vue.js code:
new Vue({
data:{
myValue:\'x\',
myOtherValue:\'y\'
},
computed: {
myComputed: myFunction(){
ret
I will address only the specific question how does vue.js know which dependencies affect which computed property?
The simple answer is that each time vue evaluates a computed property it creates a map of all the reactive properties that were accessed in the span of that call. The next time any of these reactive properties change they will trigger a reevaluation of the computed property.
If during the most recent evaluation of a computed property, one of its reactive dependencies is never reached (maybe because it is within the non-traveled path of an if/else construct), subsequent changes to that reactive property will not trigger a reevaluation of the computed property.
Observe this behavior by modifying the two reactive properties in this fiddle (by simply typing in their corresponding input boxes). A few things to note:
called
computed property is evaluated once on document load (it's triggered because it's rendered in the template).path
is set to 1
the reactive property that will be mapped as a dependency is val1
. As a result it will be the only one that can trigger a reevaluation of called
when it changes. The value of val2
can also change but will not have the same effect on called
, even though it's clearly present in the function.path
is toggled from 1
to 2
.val1
will affect called
only once more. Because path
has been set to 2
prior to that last reevaluation, val1
will not be reachable and will not be mapped as a dependency of called
any longer. Subsequent changes to its value won't trigger a reevaluation of called
from that point on. But then val2
has now been mapped as a dependency of called
and changes to it trigger the reevaluation the same way they did for val1
earlier. It will be so until the next path toggle from 2
back to 1
.Here's the code.
let path=1
let count=0
const vm=new Vue({
el:"#app",
data:{
val1:null,
val2:null,
},
computed: {
called: function(){
if (path==1){
this.val1
}
if (path==2){
this.val2
}
return "I was just called "+ ++count +" times"
}
},
methods: {
changePath(){
path = path==2 ? 1 : 2
}
}
})
and corresponding template
<div id="app">
<input v-model="val1"/> {{val1}}
<br>
<input v-model="val2"/> {{val2}}
<br>
<button @click="changePath">change path</button>
<br>
{{ called }}
</div>
From the docs it reads that: Computed properties are cached, and only re-computed on reactive dependency changes. However the following fiddle shows something a bit different.
From the fiddle if you set the flag to 2, the computed property will be re-evaluated and executed if you change myOtherValue
, however this will not happen if the flag is set to 1. I think it keeps track of your if conditions.
In the docs usually you can find links to the relevant source code. Here is the code for computed properties:
It's the reactivity system of Vue.js, not a caching system.
The data in a component will be convert to getters and setters. When you access a value via a getter, the getter will add it to the dependencies, and when you modify the value via a setter, the setter will notify everyone who depends on the value.
Here is the source code, all the magic happens in this function: https://github.com/vuejs/vue/blob/dev/src/core/observer/index.js#L131