Skip to content

Vue 3:响应式原理、Proxy、ref 与 reactive ​

一、总览:从 Vue 2 到 Vue 3 ​

  • Vue 2:递归 Object.defineProperty,难以优雅覆盖新增/删除属性、部分数组场景需补丁。
  • Vue 3:Proxy + Reflect,在「读取」路径上做 track,在「写入/删除」路径上做 trigger;配合 effect 作为订阅单元(概念上接替部分 Watcher 职责)。

二、Proxy 基础 ​

js
const proxy = new Proxy(target, handler)
  • target:被代理对象。
  • handler:get、set、deleteProperty 等陷阱函数。

Vue 中 reactive 对普通对象、ref 对原始值包装对象,本质都依赖代理与依赖映射表(WeakMap → Map → Set)。


三、简化版 reactive + effect ​

文档给出 effect 栈 + targetMap + track/trigger + reactive 迷你实现,演示:

  1. effect(fn) 执行时登记当前活跃 effect。
  2. get → track 把 effect 绑定到 target[key]。
  3. set/deleteProperty → trigger 重新运行相关 effect。

真实 Vue 还包含:递归代理策略、ref unwrap、readonly、scheduler 队列、数组/集合类型分支等。


四、Reflect 的角色 ​

  • 统一默认语义(返回值、this 绑定)。
  • 与 Proxy 陷阱协作:Reflect.get/set 等。

五、响应式 API 一览 ​

API用途
ref任意类型;原始值包在 { value } 里;模板自动解包
reactive仅对象类型(含数组、Map、Set)
shallowRef / shallowReactive浅层追踪,适合大体量替换场景
readonly深度只读代理,避免下游修改
computed派生值,带缓存
toRef / toRefs解构 reactive 不丢响应式
triggerRef手动触发 shallowRef 更新
markRaw / toRaw退出响应式体系(性能或与第三方库互操作)

ref vs reactive ​

  • 类型:ref 通用;reactive 仅限引用类型。
  • 访问:setup 内 ref 要 .value,reactive 直接点属性。
  • 整体替换:ref 可整体换 .value;reactive 不能整体替换引用(常用 ref 承载异步整块数据)。
  • 解构:reactive 直接解构会丢响应式 → toRefs。

shallow 场景 ​

大对象仅需展示、每次接口返回整体替换 → shallowRef 可减少深度代理成本。


六、effect / watch / computed 的关系 ​

  • effect:运行函数并自动追踪依赖 —— 渲染、watch 底层都与之相关。
  • computed:带缓存的派生;依赖不变不重复计算。
  • watch:显式数据源 + 回调,适合异步副作用。

七、与后续章节衔接 ​

  • 写法层面:setup、watch/watchEffect 见 03、04。
  • diff 与 PatchFlag:05。