1.Computed也是响应式的

Computed是响应式的,读取Computed会触发get,设置Computed会触发set

2.Computed如何控制缓存

计算属性是有缓存的,比如某个计算属性C,它依赖data中的A,如果没有缓存的话,每次读取C时,C都回去读取A,从而触发A的get。多次触发A的get有时候是一个非常消耗性能的操作。所以Computed必须要有缓存。

computed里面控制缓存最重要的一点就是脏数据标记为dirty, dirty是watcher的一个属性。

  • 当dirty为true时,读取computed会重新计算
  • 当dirty为false时,读取computed会使用缓存

3. 依赖的data发生变化,computed是如何更新的

页面P依赖计算属性C, 计算属性C又依赖data里面的A, computed更新步骤如下:

  1. 由于C依赖了A, A可以收集到C的watcher
  2. 当A发生变化时,会将watcher的脏数据标记位dirty设置为true
  3. 并且A会收集到页面P的watcher,A通知P进行更新,从而页面P重新读取计算属性C, 由于此时dirty为true,此时的计算属性会重新计算。
  4. computed更新完毕,重新将脏数据标记位dirty设置为false,如果其依赖的A不发生改变,那下次再进入就会读取缓存。

4. 计算属性C是如何让data中的A收集到页面P的watcher的

这其实是计算属性中一个非常巧妙的操作。来看一下核心的源码(已简化)

function createComputedGetter(key) {
    return function() { 
        // 获取到相应 key 的 computed-watcher
        var watcher = this._computedWatchers[key];
        // 如果 computed 依赖的数据变化,dirty 会变成true,
        // 从而重新计算,然后更新缓存值 watcher.value
        if (watcher.dirty) {
            watcher.evaluate();
        }        
        // 这里是 月老computed 牵线的重点,让双方建立关系
        if (Dep.target) {
            watcher.depend();
        }        
        return watcher.value
    }
}
Logo

前往低代码交流专区

更多推荐