框架响应式原理
响应式原理是框架核心。Vue2 用 Object.defineProperty:给每个属性定义 getter / setter,getter 收集依赖(Watcher),setter 通知更新;缺陷是新增属性、数组下标修改监听不到,需要 $set 兜底。Vue3 换成 Proxy:代理整个对象,拦截 get / set / deleteProperty / 数组方法,一次到位且性能更好(惰性收集,只有被读取的属性才建立依赖)。
React 的“响应式”是另一套:setState 触发 re-render,Fiber 架构把渲染拆成可中断的小任务,双缓存树(current → workInProgress)实现增量渲染。依赖追踪是 React 的弱项,所以需要 useMemo / useCallback / memo 手动声明依赖,React Compiler 正试图自动化这一步。
- Vue2:Object.defineProperty 逐属性劫持,新增属性与数组下标需 $set
- Vue3:Proxy 代理整个对象,惰性收集依赖,性能与能力双升级
- React:setState 触发整树 diff,Fiber 可中断渲染,依赖需手动 memo
JS
// 手写 mini 响应式(Vue3 核心思路) const targetMap = new WeakMap(); // 对象 -> 属性 -> 依赖集合 let activeEffect = null; function effect(fn) { activeEffect = fn; fn(); // 执行时触发 getter,完成依赖收集 activeEffect = null; } function reactive(obj) { return new Proxy(obj, { get(t, key, receiver) { // 依赖收集:把当前 effect 记到这个属性上 if (activeEffect) { let depsMap = targetMap.get(t); if (!depsMap) targetMap.set(t, (depsMap = new Map())); let dep = depsMap.get(key); if (!dep) depsMap.set(key, (dep = new Set())); dep.add(activeEffect); } return Reflect.get(t, key, receiver); }, set(t, key, val, receiver) { const res = Reflect.set(t, key, val, receiver); const dep = targetMap.get(t)?.get(key); // 派发更新 dep?.forEach(eff => eff()); return res; }, }); } // 验证:数据变 → 与之相关的 effect 自动跑 const state = reactive({ count: 0, name: "小明" }); effect(() => console.log("count 变成", state.count)); // count 变成 0 state.count++; // count 变成 1:setter 找到依赖并触发 state.name = "小红"; // 无 effect 订阅,无输出(惰性精准)
本节要点响应式 = 数据劫持 + 依赖收集 + 派发更新;Vue3 用 Proxy 解决了 Vue2 的数组与新增属性盲区。




