I have this Vue.js code:
new Vue({ data:{ myValue:'x', myOtherValue:'y' }, computed: { myComputed: myFunction(){ return this['my' + 'Value'] } } })
As you can see the computed property will be cached and it is depended only on data.myValue
. My question is how Vue.js caching system knows that run the computed function again only if myValue
is changed?
If I change the myOtherValue
variable, the myComputed
function will use the cache, and will not be run again will I call it.
I thought about several ways how it is possible. But how Vuejs doing that? I have read this article: https://vuejs.org/v2/guide/computed.html and found no answer.
And what happen in this code, what it will be depeneded on?
const flag=2 new Vue({ data:{ myValue:'x', myOtherValue:'y' }, computed: { myComputed: myFunction(){ if (flag==1){ return this['my' + 'Value'] } else return this['my' + 'Other' + 'Value'] } } })
Bonus: I will appreciate I link to the relevant function in the VueJS code: https://github.com/vuejs/vue
In Vue. js, computed properties enable you to create a property that can be used to modify, manipulate, and display data within your components in a readable and efficient manner. You can use computed properties to calculate and display values based on a value or set of values in the data model.
The Basics of Vue Reactivity Simply put, a computed property's dependencies are the reactive values that help the property that determine the value that is returned. If none of these change, then, again, the cached value will be returned. If no reactive dependency is changed, a computed property is not recalculated.
Computed Caching vs Methods Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies.
Because computed props are reactive, whenever firstName or lastName are changed, fullName will be recomputed and will always be up to date. Already we can see an advantage of computed props over watchers. This is a fairly simple example — computed props can depend on as many other properties as you need them to.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With