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)。

缺点 (痛点)

  1. 无法监听新增/删除属性:必须使用 Vue.set / Vue.delete
  2. 无法监听数组下标:Hack 了 push/pop 等 7 个方法,但直接 arr[0]=1 依然无法监听。
  3. 性能开销:初始化时必须递归遍历整个对象。如果是深层嵌套对象,启动慢。

(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 实现响应式。