vue computed 实现原理
Vue computed 实现原理
Vue 的 computed 属性是基于响应式依赖的缓存机制,其核心实现依赖于 Vue 的响应式系统和依赖收集机制。
依赖收集与缓存机制
computed 属性在初始化时会创建一个 Watcher 实例,并标记为 lazy(惰性求值)。只有当 computed 属性被访问时,才会触发其 getter 函数进行计算。计算过程中会访问其他响应式数据(如 data 或 props),从而触发这些数据的依赖收集,将当前 computed Watcher 添加到它们的依赖列表中。
惰性求值与缓存
computed 属性的值会被缓存,只有在依赖的响应式数据发生变化时才会重新计算。这是通过 Watcher 的 dirty 标志实现的:
- 初始时
dirty=true,表示需要重新计算。 - 首次访问时触发计算,并将
dirty设为false。 - 依赖数据变化时,
dirty被重新设为true,下次访问时重新计算。
代码示例与流程
以下是简化后的核心逻辑:

// 伪代码:Computed 初始化
function initComputed(vm, computed) {
const watchers = {};
for (const key in computed) {
const getter = computed[key];
watchers[key] = new Watcher(
vm,
getter,
() => {}, // 回调
{ lazy: true } // 惰性求值
);
defineComputed(vm, key, watchers[key]);
}
}
// 定义 computed 属性
function defineComputed(target, key, watcher) {
Object.defineProperty(target, key, {
get() {
if (watcher.dirty) {
watcher.evaluate(); // 重新计算
}
if (Dep.target) {
watcher.depend(); // 依赖收集
}
return watcher.value;
}
});
}
与 methods 的区别
computed具有缓存,依赖不变时直接返回缓存值。methods每次调用都会重新执行函数。computed适用于派生状态(如过滤、计算值),methods适用于事件处理或需要频繁变动的逻辑。
性能优化建议
- 避免在
computed中执行高耗操作,依赖过多数据时可能引发性能问题。 - 对于复杂计算,可结合
watch或手动缓存优化。
通过这种设计,computed 实现了高效的数据派生和缓存,是 Vue 响应式系统的核心特性之一。






