reactive 的响应式原理是 Proxy 拦截读写操作 + 依赖收集(track)+ 自动触发更新(trigger)的闭环;Proxy 替代 Object.defineProperty 实现对新增属性、数组索引等的全面拦截,通过 WeakMap 建立对象属性到副作用函数的映射,实现精准依赖追踪与深层响应式。

理解 reactive 的响应式原理,关键在于抓住“Proxy 拦截 + 依赖追踪 + 自动触发”这三步闭环。它不是给数据加个监听器就完事,而是让每一次读和写都成为可感知、可调度的信号。
Proxy 是 reactive 的执行引擎
Vue 3 不再用 Object.defineProperty,因为后者无法监听属性新增、数组索引赋值、delete 等操作。而 Proxy 能拦截 13 种内部方法(如 [[Get]]、[[Set]]、[[Has]]、[[Delete]]),覆盖所有对象基础行为。
-
get(target, key)拦截读取:每次访问state.count都会进这里,顺带做依赖收集(track) -
set(target, key, value)拦截赋值:每次修改state.count = 5都触发这里,顺带通知更新(trigger) - 所有操作都通过
Reflect.get/set转发到底层,保证语义不变,只是中间插了一道逻辑
依赖收集(track)发生在读取时
响应式不是“一创建就绑定”,而是“谁用到谁登记”。当组件渲染中读取 state.name,get 拦截器就会调用 track(state, 'name'),把当前正在运行的副作用函数(比如 render)记下来:
- 用
WeakMap存对象 → 属性 → 依赖集合的映射(targetMap) - 每个属性对应一个
Set,里面存着所有关心它的 effect - 只有在“有激活的 effect”时才收集,避免无意义注册
更新触发(trigger)发生在赋值后
当 state.age = 25 执行完毕,set 拦截器检测到值变化,就调用 trigger(state, 'age', 25, 24):
- 查
targetMap.get(state)?.get('age'),拿到所有订阅者 - 依次执行这些 effect(如重新渲染、计算属性重求值)
- 如果属性值是对象,还会递归调用
reactive(),实现深层响应式
reactive 是深度代理,不是浅层包装
它不改变原始对象结构,而是返回一个 Proxy 实例,直接代理目标本身:
- 你传入
{user: {profile: {name: 'A'}}},它会递归对user、profile也做new Proxy - 访问
state.user.profile.name时,每层get都触发一次track,形成完整依赖链 - 修改
state.user.profile.name = 'B',只触发最内层的trigger,不会误刷整个对象


















