vue3 computed原理分析

220 阅读1分钟

引言

computed 是如何做到数据的缓存?思路:依赖不变化,直接返回旧的值,依赖变化返回新的值

const count = ref(1)
const computedValue = computed(() => count.value + 1) // computedValue.value 为 2
count.value++ // 依赖更新了
computedValue.value = 3

所以只要 count.value 不变就永远不会让 computedValue 触发更新逻辑。得到以下结论:

  • 对 count.value 做数据劫持,当它改动的时候(set) 我们触发 computed.value 逻辑更新
  • 对 computed.value 做数据劫持,当有人获取它的时候 (get) 判断依赖的值是否有发生过变化,有 => 更新,没有 => 直接返回旧的值

源码解析

tips:此处只保留了和我们思路的相关代码

export class ComputedRefImpl<T> {
    
  // 我们就是通过 dirty 变量来判断依赖是否发生过变化
  public _dirty = true

  get value() {
    // 依赖变化了 =》 触发更新逻辑
    if (self._dirty) {
      self._dirty = false
      self._value = self.effect.run()! // 返回新的值
      // run 方法里面会有一个步骤 return this.fn()
      // 这个 fn 就是我们一开始传进去的 () => count.value + 1,所以值就更新了
    }
    // 没有变化直接返回旧的值
    return self._value
  }
}

总结:当依赖变化 _dirty 变为 true,当我们再次读取 computed 的时候就会走更新逻辑,如果不变化就直接返回原来的值

后话

下一遍文章会对 vue2、vue3 响应式做一个简单的对比,尽量争取这周吧,下周开始要准备期末考试了 2022.5.24 0:25 上海浦东