vue框架computed实现原理
Vue 中 computed 的实现原理
Vue 的 computed 属性是基于响应式依赖的缓存机制,通过以下核心机制实现:
依赖收集与响应式
computed 属性在初始化时会创建一个 Watcher 实例,并将该 computed 属性的 getter 函数作为求值函数。当首次访问 computed 属性时,会执行 getter 函数,触发依赖的响应式数据的 getter,从而将这些依赖收集到当前 Watcher 的依赖列表中。

缓存机制
computed 属性具有缓存特性,只有当其依赖的响应式数据发生变化时,才会重新计算。Vue 通过 dirty 标志位控制是否需要重新计算。初始时 dirty 为 true,表示需要计算;计算完成后 dirty 置为 false。只有当依赖变更时,dirty 才会被重新置为 true。
惰性求值
computed 属性是惰性求值的,只有在模板或代码中实际访问该属性时才会触发计算。如果依赖未变化,则直接返回缓存值,避免不必要的计算开销。

实现伪代码
以下是简化后的 computed 实现逻辑:
class Watcher {
constructor(vm, getter, cb, options) {
this.vm = vm;
this.getter = getter;
this.dirty = true; // 初始时需要计算
this.value = undefined;
this.deps = [];
}
evaluate() {
this.value = this.getter.call(this.vm);
this.dirty = false; // 计算完成
}
update() {
this.dirty = true; // 依赖变更,标记需要重新计算
}
}
function defineComputed(vm, key, getter) {
const watcher = new Watcher(vm, getter);
Object.defineProperty(vm, key, {
get() {
if (watcher.dirty) {
watcher.evaluate();
}
return watcher.value;
}
});
}
与 methods 的区别
computed 与 methods 的关键区别在于缓存机制。computed 只在依赖变化时重新计算,而 methods 每次调用都会执行函数。对于需要频繁计算且依赖固定的场景,computed 性能更优。
注意事项
- 避免在
computed中执行异步操作或副作用操作,它应是纯函数。 computed默认只有 getter,但可以通过显式声明 setter 实现双向绑定。- 在 Vue 3 中,
computed通过Ref和effect实现,原理类似但基于 Proxy 的响应式系统。






