BaseHandlers 是 Vue 3 响应式模块中定义的一组 Proxy 处理器,包含 get/set/has/ownKeys 等 trap 实现,用于创建 reactive、readonly 等不同语义的响应式代理,其核心在于 get 中依赖收集(track)与 set 中更新触发(trigger),并按需提供 mutable、readonly、shallow 等多套变体以精确控制响应式行为。

Vue 3 的响应式系统核心依赖于 Proxy 和一系列 BaseHandlers,它不是直接拦截对象属性访问,而是通过精心设计的 get 和 set 捕获器,配合依赖收集与触发机制,实现细粒度、可追踪的响应式更新。
BaseHandlers 是什么?
BaseHandlers 是 Vue 3 响应式模块中定义的一组 Proxy 处理器(handler),位于 reactivity/src/baseHandlers.ts。它不直接暴露给用户,而是被 createReactiveObject 等内部函数调用,用于创建不同类型的响应式代理(如 reactive、readonly、shallowReactive)。
它本质上是一组预设的 get / set / has / ownKeys 等 trap 实现,其中 get 和 set 是最关键的两个。
Get 拦截:如何读取时收集依赖?
当访问响应式对象的某个属性(例如 obj.count)时,get trap 被触发。它的核心逻辑包括:
立即学习“前端免费学习笔记(深入)”;
-
判断是否为内置 Symbol 方法或原型方法调用:如
obj.toString、obj[Symbol.iterator],这类访问不触发依赖收集,直接返回原始值或绑定 this 后返回。 -
对 ref 解包:若目标是 ref,且访问的是
.value,则自动解包并建立对 ref.value 的依赖;其他属性访问则按普通对象处理。 -
依赖收集(track):调用
track(target, 'get', key),将当前正在执行的副作用(effect)与该对象 + 属性的组合关联起来,存入依赖图(depsMap)中。 -
递归响应式包装:如果读取的值是对象或数组,且尚未被代理,则调用
reactive()包装它(惰性代理),确保深层响应式。
注意:只有在存在活跃的 effect(比如组件 render 函数执行中)时,track 才会真正注册依赖;否则跳过,避免无效收集。
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
Set 拦截:如何赋值时触发更新?
当设置属性(如 obj.count = 5)时,set trap 执行以下关键步骤:
-
区分新增/修改:通过
hasOwnProperty(target, key)或Reflect.has(target, key)判断是已有属性更新还是新增属性(尤其对数组索引、动态 key 很重要)。 -
值是否真的变化:对基本类型做
===对比;对对象类型默认认为变化(因无法深度比较),但会跳过 NaN 等边界情况。 -
执行原始赋值:使用
Reflect.set(target, key, value, receiver)完成真实写入,保证原型链和 setter 行为正常。 -
触发依赖更新(trigger):调用
trigger(target, 'set', key, newValue, oldValue),通知所有依赖该对象 + 属性的 effect 重新执行。 -
特殊处理数组长度变更:如
arr.length = 2,会额外触发对'length'和已删除索引范围(如 2、3…)的更新通知,确保遍历逻辑(如 v-for)能响应。
对于 readonly 类型的 handler,set 会直接抛出警告(开发模式)或静默失败(生产模式),不执行写入。
为什么需要多个 handler 变体?
Vue 3 并非只有一套 BaseHandlers,而是导出了多组 handler:
-
mutableHandlers:对应reactive(),支持读写,完整依赖跟踪与触发。 -
readonlyHandlers:对应readonly(),get支持解包与 track,但set/deleteProperty禁止修改。 -
shallowHandlers:对应shallowReactive(),get不对返回的对象递归代理,仅代理顶层。 -
shallowReadonlyHandlers:结合前两者特性,顶层只读 + 不深层代理。
这种分层设计让 Vue 能在不同语义场景下复用同一套拦截逻辑,同时保持行为精确可控——不是靠运行时判断,而是靠 Proxy handler 的静态绑定。
理解 BaseHandlers 的 get/set 并不意味着要重写响应式系统,但它揭示了 Vue 3 响应式“精准”背后的工程选择:利用 Proxy 的原子级拦截能力,把依赖关系建模为「对象 × 属性 × effect」三元组,并在最恰当的时机建立和触发它。不复杂但容易忽略。

















