Skip to content

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

一、总览:从 Vue 2 到 Vue 3

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

二、Proxy 基础

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

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


三、简化版 reactive + effect

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

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

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


四、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/watchEffect0304
  • diff 与 PatchFlag05