vue computed 实现原理
Vue computed 实现原理
响应式依赖收集
Vue的computed属性基于响应式系统实现。当组件初始化时,computed属性会创建一个计算watcher,这个watcher会在getter被调用时收集依赖的响应式数据。每个computed属性都有自己的watcher实例,其中包含一个dirty标志位用于缓存控制。
惰性求值与缓存
计算属性具有惰性求值特性,只有当依赖的响应式数据变化时才会重新计算。计算watcher的getter会在首次访问时执行一次,并将结果缓存。当依赖数据未变化时,直接返回缓存值而不重新计算。

依赖触发更新流程
当computed依赖的响应式数据发生变化时,会触发setter通知,使得计算watcher的dirty标志变为true。下次访问该computed属性时,由于dirty为true,会重新执行getter计算新值并更新缓存。

与渲染watcher的关联
计算属性通常被模板引用,因此计算watcher会作为渲染watcher的依赖存在。当计算属性重新计算后,会触发渲染watcher的更新,从而驱动视图重新渲染。
实现核心代码逻辑
// 简化版实现原理
class Watcher {
constructor(vm, fn, options) {
this.vm = vm
this.dirty = options.lazy
this.getter = fn
this.value = this.lazy ? undefined : this.get()
}
get() {
pushTarget(this)
const value = this.getter.call(this.vm)
popTarget()
return value
}
update() {
this.dirty = true
}
evaluate() {
this.value = this.get()
this.dirty = false
}
}
function defineComputed(target, key, userDef) {
const watcher = new Watcher(target, userDef.get, { lazy: true })
Object.defineProperty(target, key, {
get() {
if (watcher.dirty) {
watcher.evaluate()
}
return watcher.value
}
})
}
与method的区别
计算属性基于依赖缓存,只有相关依赖发生改变才会重新计算。而method每次调用都会执行函数体。计算属性适用于派生状态,而method更适合事件处理等需要主动触发的场景。
与watch的区别
计算属性是声明式的值计算,自动追踪依赖。watch需要显式指定监听目标,更适合执行副作用操作。计算属性必须有返回值,而watch不需要。






