vue computed的实现
Vue computed 的实现原理
Vue 的 computed 属性是基于响应式依赖进行缓存的计算属性。其核心实现依赖于 Vue 的响应式系统和 Watcher 机制。
初始化 computed 属性
在 Vue 实例初始化阶段,computed 属性会被遍历并转化为 getter/setter 形式。每个 computed 属性会创建一个对应的 Watcher 实例,标记为 lazy(惰性求值)。
function initComputed(vm, computed) {
const watchers = vm._computedWatchers = Object.create(null);
for (const key in computed) {
const getter = typeof computed[key] === 'function'
? computed[key]
: computed[key].get;
watchers[key] = new Watcher(vm, getter, noop, { lazy: true });
defineComputed(vm, key, computed[key]);
}
}
定义 computed 属性
通过 Object.defineProperty 将 computed 属性挂载到 Vue 实例上,并定义 getter/setter:

function defineComputed(target, key, userDef) {
const shouldCache = !isServerRendering();
if (typeof userDef === 'function') {
sharedPropertyDefinition.get = shouldCache
? createComputedGetter(key)
: userDef;
sharedPropertyDefinition.set = noop;
} else {
sharedPropertyDefinition.get = userDef.get
? shouldCache && userDef.cache !== false
? createComputedGetter(key)
: userDef.get
: noop;
sharedPropertyDefinition.set = userDef.set || noop;
}
Object.defineProperty(target, key, sharedPropertyDefinition);
}
计算属性的 getter 实现
核心的 computed getter 会检查依赖是否变化,决定是否重新计算值:
function createComputedGetter(key) {
return function computedGetter() {
const watcher = this._computedWatchers && this._computedWatchers[key];
if (watcher) {
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) {
watcher.depend();
}
return watcher.value;
}
};
}
Watcher 的 evaluate 方法
当依赖变化时(dirty 为 true),会调用 evaluate 重新计算值:

class Watcher {
evaluate() {
this.value = this.get();
this.dirty = false;
}
}
依赖收集过程
computed 属性在计算时会触发其依赖的响应式数据的 getter,从而建立依赖关系。当依赖变化时,会触发 computed watcher 的 update 方法:
class Watcher {
update() {
if (this.lazy) {
this.dirty = true;
} else {
// 其他处理
}
}
}
缓存机制
computed 属性只有在依赖变化时才会重新计算(dirty 为 true 时),否则直接返回缓存的值。这是 computed 与 method 的本质区别。
与普通响应式数据的区别
- computed 属性是惰性求值的,只有被访问时才会计算
- computed 具有缓存机制,依赖不变时直接返回缓存值
- computed 的更新是同步的,而 watch 可以是异步的
这种实现方式使得 computed 属性在 Vue 应用中能够高效地处理派生状态,避免不必要的重复计算。






