How vuejs knows the depenedencies of computed property for caching?

前端 未结 3 1377
猫巷女王i
猫巷女王i 2021-02-01 16:21

I have this Vue.js code:

new Vue({
  data:{
         myValue:\'x\',
         myOtherValue:\'y\'
  },
  computed: {
       myComputed: myFunction(){
          ret         


        
相关标签:
3条回答
  • 2021-02-01 16:39

    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:

    • the called computed property is evaluated once on document load (it's triggered because it's rendered in the template).
    • because the 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.
    • When you click on the "Change Path" button, path is toggled from 1 to 2.
    • right after the path switch, note that a change to 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>
    
    0 讨论(0)
  • 2021-02-01 16:46

    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.

    1. https://jsfiddle.net/z11fe07p/267/

    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:

    • https://github.com/search?utf8=%E2%9C%93&q=repo%3Avuejs%2Fvue+extension%3Ajs+%22computed%22&type=Code
    0 讨论(0)
  • 2021-02-01 16:51

    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

    0 讨论(0)
提交回复
热议问题