Vue2 vs Vue3 的 计算属性 实现区别

🎯 Vue2 vs Vue3 计算属性实现区别总结
| 对比点 | Vue2 computed | Vue3 computed |
|---|---|---|
| 响应式机制 | Object.defineProperty + 依赖收集 |
Proxy + 响应式追踪系统 |
| 延迟执行 | 支持懒执行 ✅ | 支持懒执行 ✅ (效果更优) |
| 缓存机制 | 有缓存,依赖不变不重新计算 ✅ | 有缓存,依赖不变不重新计算 ✅(更准确) |
| 手动控制 | 只能 readonly | 支持 writable 计算属性(可以 get/set)✅ |
| 底层依赖追踪 | 依赖通过 Dep 收集 | 依赖通过 effect 追踪 |
| 性能 | 更容易多余依赖 / 重复计算 | 精确追踪依赖,性能更优 ✅ |
| 错误提示 | 较少,debug 不友好 | Vue3 devtools 提供 computed 调试 |
Vue2 computed 底层流程
- 创建 Vue 实例时,遍历 computed 选项,给每个 computed 生成一个 Watcher(lazy 类型,不立即执行)
- computed 的 getter 什么时候第一次被访问,就什么时候去执行内部函数。
- 执行 getter 时,会收集依赖(谁用到了这个 computed,就追踪谁)。
- 后续依赖变化时,computed Watcher 被标记为 dirty,下次访问才重新计算。
关键特点:
- 有缓存(依赖没变就不重新算)
- 懒执行
- 依赖收集是基于 Dep.target,容易出问题(比如依赖乱收集)
Vue3 computed 底层流程
- computed 本质是用
effect+ref实现的。 - 创建 computed 的时候,内部创建一个 reactive effect(lazy = true),不主动执行。
- 第一次访问
.value,触发 effect,收集依赖,执行 getter。 - 依赖变化时,computed 触发 scheduler,标记为 dirty,下一次再访问时重新计算。
import { computed, ref } from 'vue';
const count = ref(1);
const double = computed(() => count.value * 2);
console.log(double.value); // 2
count.value++;
console.log(double.value); // 4
✅ Vue3 的 computed 特性比 Vue2 更完善:
- 依赖追踪更准确(Vue3 reactive 内部自己管理依赖栈,不靠 Dep.target)
- 支持
computed({ get, set })可读可写:
const count = ref(0);
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1;
}
});
plusOne.value = 10;
console.log(count.value); // 9
💬 Vue2 的 computed 只能 readonly,Vue3可以双向绑定 computed!
⚡ 总结一句话
- Vue2 computed:
defineProperty劫持,依赖收集粗放,容易出问题。 - Vue3 computed:
Proxy劫持 + 精准依赖追踪 + effect 调度,性能更好,功能更强!

浙公网安备 33010602011771号