joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

Vue 3 computed 原理解析总结

Vue 3 的 computed 是基于 观察者模式(Observer Pattern) 和 惰性求值(Lazy Evaluation) 实现的响应式数据派生机制,其核心原理可总结如下:


  1. 核心角色
    角色 Vue 3 对应部分 作用

Subject(被观察者) ref / reactive 数据(如 count) 存储数据,并在变更时通知观察者
Observer(观察者) computedReactiveEffect 订阅依赖数据,并在数据变化时标记自身为 dirty
Dependency(依赖管理器) Vue 的 depsMap 系统 记录 computed 与响应式数据的订阅关系


  1. 核心流程
    (1) 创建 computed
    javascript
    const count = ref(0);
    const double = computed(() => count.value * 2);
  • 初始化:
    • 将计算函数 () => count.value * 2 包装成 ReactiveEffect(观察者)。
    • dirty 初始为 true(首次访问必须计算)。

(2) 首次访问(依赖收集)
javascript
console.log(double.value); // 触发计算

  1. 执行计算函数,读取 count.value
  2. countgetter 检测到当前有活动的 effect(即 doubleReactiveEffect),将其加入自己的依赖列表(deps)。
  3. 计算结果(0)并缓存,dirty 设为 false

(3) 依赖数据变更
javascript
count.value++; // 修改数据

  1. countsetter 触发,遍历所有订阅它的 effect(即 doubleReactiveEffect)。
  2. double 标记为 dirty: true(但不立即计算,惰性更新)。

(4) 再次访问(惰性更新)
javascript
console.log(double.value); // 重新计算

  1. 检查 dirty
    • dirty === true → 重新执行计算函数,更新缓存,dirty 设为 false
    • dirty === false → 直接返回缓存值(跳过计算)。
  2. 返回最新结果(2)。

  1. 关键机制
    机制 作用 优势

dirty 标志位 控制是否重新计算 避免同一事件循环内的重复计算,提升性能
惰性求值(Lazy) 只有访问时才计算 节省资源,避免不必要的计算
动态依赖收集 每次执行计算函数时重新收集依赖 自动适应条件分支(如 if 语句)
缓存机制 依赖未变化时直接返回旧值 减少重复计算,提高效率


  1. watch 的区别
    特性 computed watch / watchEffect

触发时机 惰性(读取时计算) 立即(依赖变化立即执行)
缓存 ✅ 有缓存 ❌ 无缓存
适用场景 派生数据(如过滤、计算属性) 副作用(如请求数据、DOM 操作)


  1. 总结
  • computed 是一个观察者,订阅其依赖的响应式数据(如 ref / reactive)。
  • 依赖变化时,仅标记 dirty: true,不立即计算(惰性更新)。
  • 下次访问时,若 dirty 则重新计算,否则返回缓存值。
  • 优势:自动依赖跟踪、精确更新、高性能缓存。

一句话总结:
computed 通过观察者模式 + dirty 标志位 + 惰性求值,实现高效、精确的派生数据管理。 🚀

posted on 2025-06-10 22:44  joken1310  阅读(137)  评论(0)    收藏  举报