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

image

🎯 Vue2 vs Vue3 计算属性实现区别总结

对比点 Vue2 computed Vue3 computed
响应式机制 Object.defineProperty + 依赖收集 Proxy + 响应式追踪系统
延迟执行 支持懒执行 ✅ 支持懒执行 ✅ (效果更优)
缓存机制 有缓存,依赖不变不重新计算 ✅ 有缓存,依赖不变不重新计算 ✅(更准确)
手动控制 只能 readonly 支持 writable 计算属性(可以 get/set)✅
底层依赖追踪 依赖通过 Dep 收集 依赖通过 effect 追踪
性能 更容易多余依赖 / 重复计算 精确追踪依赖,性能更优 ✅
错误提示 较少,debug 不友好 Vue3 devtools 提供 computed 调试

Vue2 computed 底层流程

  1. 创建 Vue 实例时,遍历 computed 选项,给每个 computed 生成一个 Watcher(lazy 类型,不立即执行)
  2. computed 的 getter 什么时候第一次被访问,就什么时候去执行内部函数。
  3. 执行 getter 时,会收集依赖(谁用到了这个 computed,就追踪谁)。
  4. 后续依赖变化时,computed Watcher 被标记为 dirty,下次访问才重新计算。

关键特点:

  • 有缓存(依赖没变就不重新算)
  • 懒执行
  • 依赖收集是基于 Dep.target,容易出问题(比如依赖乱收集)

Vue3 computed 底层流程

  1. computed 本质是用 effect + ref 实现的。
  2. 创建 computed 的时候,内部创建一个 reactive effect(lazy = true),不主动执行。
  3. 第一次访问 .value,触发 effect,收集依赖,执行 getter。
  4. 依赖变化时,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 computeddefineProperty 劫持,依赖收集粗放,容易出问题。
  • Vue3 computedProxy 劫持 + 精准依赖追踪 + effect 调度,性能更好,功能更强!

posted @ 2025-04-27 16:56  闲云-野鹤  阅读(112)  评论(0)    收藏  举报