vue computed实现机制
Vue computed 实现机制
Vue 的 computed 属性是基于响应式依赖的缓存机制,其核心实现依赖于 Vue 的响应式系统和依赖收集。
依赖收集与响应式
Vue 通过 Object.defineProperty 或 Proxy(Vue 3)劫持数据的访问和修改。当计算属性被访问时,会触发其 getter 函数,此时 Vue 会将当前计算属性和其依赖的响应式数据建立关联。
// 伪代码:计算属性初始化
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]);
}
}
缓存机制
计算属性会缓存计算结果,只有当其依赖的响应式数据发生变化时,才会重新计算。这是通过 dirty 标志实现的:
- 初次访问时,计算属性会执行计算并缓存结果。
- 依赖数据变化时,标记
dirty为true,下次访问时重新计算。 - 未变化时直接返回缓存值。
// 伪代码:计算属性 getter
function createComputedGetter(key) {
return function computedGetter() {
const watcher = this._computedWatchers[key];
if (watcher.dirty) {
watcher.evaluate(); // 重新计算
}
if (Dep.target) {
watcher.depend(); // 收集依赖
}
return watcher.value;
};
}
与 Watch 的区别
computed是惰性求值,依赖变化时才重新计算。watch是主动监听,适合执行副作用(如异步操作)。computed必须有返回值,watch不需要。
性能优化
- 避免在计算属性中执行耗时操作。
- 减少不必要的依赖,拆分复杂计算属性。
- Vue 3 的
computed基于Proxy优化了依赖追踪效率。
实现流程总结
- 初始化阶段,为每个计算属性创建独立的
Watcher。 - 访问计算属性时触发
getter,进行依赖收集。 - 依赖变化时标记
dirty,下次访问时重新计算。 - 无变化时直接返回缓存值,避免重复计算。







