Vue 响应式的核心是「数据劫持 + 依赖收集 + 派发更新」:读取数据时记录当前正在执行的副作用(组件渲染函数、computed 等),修改数据时通知这些副作用重新执行。

Vue 2:基于 Object.defineProperty 递归遍历对象属性,把 getter/setter 转为响应式。依赖收集在 getter 中完成(每个属性持有一个 Dep),setter 触发通知。局限:

  • 初始化时要递归遍历全部属性,大对象有性能开销;
  • 新增/删除属性检测不到,需 Vue.set/Vue.delete
  • 数组通过重写 push 等变异方法实现,通过下标改元素不触发更新。

Vue 3:改用 Proxy 代理整个对象,按需惰性处理嵌套对象,天然支持新增/删除属性和数组下标、长度变化,还能代理 Map/Set;配合 Reflect 处理 this 指向。依赖结构也从 Dep 的订阅模式重构为基于 effect 的 track/trigger。

易错点:defineProperty 拦截的是属性而非对象,这是两代方案差异的根源。追问方向:refreactive 的区别、computed 的缓存实现、watchEffect 的依赖收集时机。