vue computed实现机制
Vue computed 实现机制
Vue 的 computed 属性是基于响应式依赖的缓存机制,其核心实现依赖于 Vue 的响应式系统和依赖收集。以下是其实现机制的关键点:
依赖收集与触发
computed 属性在初始化时会创建一个 Watcher 实例,并标记为 lazy(惰性求值)。当首次访问 computed 属性时,会执行其 getter 函数,触发依赖收集。此时,所有在 getter 中访问的响应式数据(如 data 或 props)会被记录为依赖。

// 伪代码:Watcher 的初始化
new Watcher(vm, getter, { lazy: true });
缓存机制
computed 属性会缓存计算结果。只有当其依赖的响应式数据发生变化时,才会重新计算。否则直接返回缓存值。这一机制通过 dirty 标志位实现:

- 初始时
dirty = true,表示需要重新计算。 - 计算完成后
dirty = false,后续访问直接返回缓存值。 - 依赖变化时,
dirty被设为true,触发下次访问时重新计算。
惰性求值
computed 的求值是惰性的,即只有在模板或代码中实际访问时才会计算。这与 methods 或 watch 的即时执行不同。
实现流程
- 初始化阶段:Vue 遍历
computed对象,为每个属性创建对应的Watcher,并绑定getter。 - 首次访问:触发
getter,执行依赖收集,计算结果并缓存。 - 依赖更新:当依赖数据变化时,通知
computed Watcher标记dirty为true。 - 重新计算:下次访问时,若
dirty为true,则重新计算并更新缓存。
代码示例
以下是一个简化的 computed 实现逻辑:
class Watcher {
constructor(vm, expOrFn, options) {
this.vm = vm;
this.lazy = !!options.lazy;
this.dirty = this.lazy;
this.getter = expOrFn;
this.value = this.lazy ? undefined : this.get();
}
get() {
pushTarget(this); // 标记当前 Watcher 为依赖收集目标
const value = this.getter.call(this.vm);
popTarget(); // 恢复之前的 Watcher
return value;
}
update() {
if (this.lazy) {
this.dirty = true; // 标记为需要重新计算
} else {
this.get();
}
}
}
与 watch 的区别
computed是计算属性,适用于派生状态;watch是监听机制,适用于副作用操作。computed自动追踪依赖,watch需显式指定监听目标。computed具有缓存,watch每次触发都会执行回调。
通过这种机制,Vue 的 computed 实现了高效、自动化的依赖管理和缓存优化。






