vue computed 实现原理
在 Vue.js 中,computed 属性的实现原理主要依赖于响应式系统和依赖收集机制。以下是 computed 属性的核心实现原理:
1. 响应式依赖
Vue 的 computed 属性是基于其响应式系统实现的。每个计算属性本质上是一个 getter 函数,当计算属性被访问时,Vue 会执行这个 getter 函数,并收集其中访问的所有响应式依赖(如 data 或 props 中的属性)。

2. 依赖收集
Vue 使用 Watcher 类来跟踪依赖关系。计算属性的 getter 会被包裹在一个 Watcher 中,当计算属性被访问时:
- 执行
getter函数。 - 在
getter执行过程中,如果访问了其他响应式数据,这些数据的getter会触发,将当前的Watcher添加到它们的依赖列表中(即“依赖收集”)。
3. 缓存机制
计算属性具有缓存功能:

- 只有当其依赖的响应式数据发生变化时,计算属性才会重新计算。
- 如果依赖没有变化,多次访问计算属性会直接返回缓存的值,而不会重新执行
getter。
4. 惰性求值
计算属性是惰性的,即:
- 如果没有访问计算属性,它的
getter不会执行。 - 只有在其依赖的响应式数据变化时,才会标记为“脏”(
dirty),并在下次访问时重新计算。
5. 实现伪代码
以下是简化的 computed 实现逻辑:
class Watcher {
constructor(vm, fn) {
this.vm = vm;
this.getter = fn;
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(target, key, getter) {
const watcher = new Watcher(target, getter);
Object.defineProperty(target, key, {
get() {
if (watcher.dirty) {
watcher.evaluate();
}
return watcher.value;
}
});
}
6. 与 methods 的区别
- 缓存:
computed会缓存结果,而methods每次调用都会重新执行。 - 响应式:
computed自动追踪依赖,而methods需要手动调用。
7. 与 watch 的区别
- 用途:
computed适合派生状态,watch适合副作用操作。 - 性能:
computed有缓存,watch每次变化都会执行回调。
这种设计使得 computed 在需要基于响应式数据派生复杂逻辑时非常高效,避免了不必要的重复计算。






