返回

剖析Vue源码——探究Watcher的实现之二:computedWatcher

前端

computedWatcher:细细品味动态属性的奥秘

在之前的篇章中,我们领略了watcher的魅力,揭示了其运行的机制。而computedWatcher是Vue.js中另一种独具特色的watcher,它更为隐秘,却也同样重要。现在,让我们一起踏上探索computedWatcher的奇妙之旅吧!

computedWatcher肩负着计算属性的重任,当计算属性的getter被触发时,它便会悄然登场。它的职责是根据计算属性的key从watcher列表中找出对应的watcher,并判断watcher依赖的值是否有更新。若有更新,它将重新计算值,最后返回watcher的value。

这看似简单的过程,却凝聚了Vue.js团队的智慧结晶。透过对computedWatcher的剖析,我们可以领悟到Vue.js的巧妙之处,以及其对细节的精雕细琢。

揭秘computedWatcher的运作流程

computedWatcher的运作流程与watcher基本一致,但也有其自身的独特之处。让我们一步步揭开它的运作奥秘:

  1. getter触发,开启计算之旅: 当计算属性的getter被调用时,computedWatcher便被唤醒。它首先从watcher列表中找到与计算属性key对应的watcher。
  2. 依赖值变更,触发重新计算: 如果发现依赖项的值发生了变化,computedWatcher便会重新计算计算属性的值。这一步至关重要,它保证了计算属性始终与依赖项保持同步。
  3. 计算值更新,传递最新结果: 计算完成后,computedWatcher会将最新计算出的值存储在watcher的value中,以便其他地方使用。

深入剖析computedWatcher的实现

为了更深入地理解computedWatcher的实现,我们不妨一窥其代码:

export default class ComputedWatcher extends Watcher {
  constructor(vm, expOrFn, cb, options, isRenderWatcher) {
    super(vm, expOrFn, cb, options, isRenderWatcher)
    this.lazy = true // computed watcher default lazy:true
    this.dirty = this.lazy // computed watcher default dirty = lazy
    this.computedWatcher = true
    this.value = undefined
    this.dep = new Dep()
  }

  // ... 更多代码 ...
}

从这段代码中,我们可以看到computedWatcher继承自Watcher类,并拥有自己独有的属性和方法。其中,lazy属性表示computedWatcher默认是惰性的,即只有在访问计算属性时才会计算值。dirty属性与lazy属性相关,它指示computedWatcher是否需要重新计算。computedWatcher属性则表明这是一个computedWatcher。

computedWatcher与watcher的异同对比

computedWatcher与watcher有很多相似之处,但也有显著的不同:

  • 相同点:
    • 都是基于依赖追踪的机制
    • 都可以侦听数据的变化
    • 都可以触发更新视图
  • 不同点:
    • computedWatcher计算的是计算属性的值,而watcher监视的是数据的变化
    • computedWatcher默认是惰性的,只有在访问计算属性时才会计算值,而watcher在数据变化时就会触发更新
    • computedWatcher的依赖项是计算属性的getter函数,而watcher的依赖项是普通属性

结语

computedWatcher是Vue.js中一个巧妙的机制,它为计算属性的实现提供了有力支撑。通过深入剖析computedWatcher,我们不仅领略了Vue.js的智慧与精妙,也加深了对响应式系统的理解。在未来的开发中,愿我们都能娴熟运用computedWatcher,为用户带来更加流畅、更加动态的应用体验。