剖析Vue源码——探究Watcher的实现之二:computedWatcher
2023-12-13 13:23:28
computedWatcher:细细品味动态属性的奥秘
在之前的篇章中,我们领略了watcher的魅力,揭示了其运行的机制。而computedWatcher是Vue.js中另一种独具特色的watcher,它更为隐秘,却也同样重要。现在,让我们一起踏上探索computedWatcher的奇妙之旅吧!
computedWatcher肩负着计算属性的重任,当计算属性的getter被触发时,它便会悄然登场。它的职责是根据计算属性的key从watcher列表中找出对应的watcher,并判断watcher依赖的值是否有更新。若有更新,它将重新计算值,最后返回watcher的value。
这看似简单的过程,却凝聚了Vue.js团队的智慧结晶。透过对computedWatcher的剖析,我们可以领悟到Vue.js的巧妙之处,以及其对细节的精雕细琢。
揭秘computedWatcher的运作流程
computedWatcher的运作流程与watcher基本一致,但也有其自身的独特之处。让我们一步步揭开它的运作奥秘:
- getter触发,开启计算之旅: 当计算属性的getter被调用时,computedWatcher便被唤醒。它首先从watcher列表中找到与计算属性key对应的watcher。
- 依赖值变更,触发重新计算: 如果发现依赖项的值发生了变化,computedWatcher便会重新计算计算属性的值。这一步至关重要,它保证了计算属性始终与依赖项保持同步。
- 计算值更新,传递最新结果: 计算完成后,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,为用户带来更加流畅、更加动态的应用体验。