Vue 响应式原理详解
1. 面试题
Q: Vue 2 和 Vue 3 的响应式原理有什么区别?为什么 Vue 3 要换成 Proxy?
2. 核心解答
(1) Vue 2:Object.defineProperty
Vue 2 递归遍历 data 对象,将每个属性转换为 getter/setter。
- Getter: 收集依赖 (Dep)。
- Setter: 触发更新 (Notify)。
缺点 (痛点):
- 无法监听新增/删除属性:必须使用
Vue.set / Vue.delete。
- 无法监听数组下标:Hack 了 push/pop 等 7 个方法,但直接
arr[0]=1 依然无法监听。
- 性能开销:初始化时必须递归遍历整个对象。如果是深层嵌套对象,启动慢。
(2) Vue 3:Proxy
Vue 3 使用 ES6 Proxy 拦截整个对象的操作。
- 能力强:能拦截 Get/Set/Delete/Has 等 13 种操作。完美支持新增属性、数组下标修改。
- 惰性代理 (Lazy):只有访问到深层属性时,才会对那一层进行代理。初始化速度极快。
(3) 核心模块
- Reactive: 创建 Proxy。
- Effect (副作用):相当于 Vue 2 的 Watcher。
- Track (追踪):Getter 中收集 Effect。
- Trigger (触发):Setter 中触发 Effect。
3. 面试加分项
Q: 为什么 Vue 3 还需要 ref?
Proxy 只能代理对象,不能代理基本类型 (number/string)。
ref(0) 本质是创建一个包装对象 { value: 0 },通过 value 的 get/set 实现响应式。