1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const targetMap = new WeakMap();
function reactive(obj) { return new Proxy(obj, { get(target, key, receiver) { const res = Reflect.get(target, key, receiver); track(target, key); return isObject(res) ? reactive(res) : res; }, set(target, key, val, receiver) { const oldVal = target[key]; const hadKey = hasOwn(target, key); const result = Reflect.set(target, key, val, receiver); if (!hadKey) trigger(target, key, 'add'); else if (oldVal !== val) trigger(target, key, 'set'); return result; }, deleteProperty(target, key) { const hadKey = hasOwn(target, key); const result = Reflect.deleteProperty(target, key); if (hadKey) trigger(target, key, 'delete'); return result; } }); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| Vue2 响应式 ├─ 入口:new Vue() → initState() → initData() ├─ 遍历 data → observe(obj) → new Observer() ├─ 为每个属性 defineReactive → getter/setter ├─ Dep 管理依赖,Watcher 订阅 └─ 缺陷:新增属性、数组索引、深层递归
Vue3 响应式 ├─ 入口:createApp() → setup() → reactive() ├─ 一次性 new Proxy() 代理根对象 ├─ track() 收集,trigger() 派发 ├─ WeakMap 全局缓存,懒代理 └─ 解决 Vue2 所有盲区,性能更好
|
“Vue2 通过 Object.defineProperty 递归属性实现数据劫持,新增/删除属性无法自动响应;
Vue3 改用 Proxy 整体代理对象,能拦截 13 种操作,新增/删除属性、数组索引均可自动追踪,且采用懒代理策略,启动更快。”