Javascript/Vue
响应式原理
Vue 2 的响应式原理
实现方式
Vue 2 使用 Object.defineProperty 对对象的每个属性进行劫持,在属性被读取或修改时拦截操作,进而通知视图更新。
核心流程:
-
遍历对象所有属性。
-
用
Object.defineProperty递归绑定getter和setter。 -
getter:依赖收集(把当前组件 watcher 加进去)。 -
setter:触发依赖更新(通知 watcher 更新视图)。
优点:
简单直观,浏览器支持好。
局限:
- 无法监听新增属性或删除属性。
- 无法监听数组的索引和长度变化。
- 深度嵌套对象会递归,性能差。
- 运行时动态添加属性需要 Vue.set() 才能响应。
Vue 3 的响应式原理
实现方式
Vue 3 使用 Proxy 代理整个对象,不再遍历属性,而是一次性代理,通过拦截 get/set 等操作实现响应式。
核心流程:
-
使用
Proxy包装整个对象。 -
get():收集依赖。 -
set():触发依赖更新。 -
访问深层属性时,按需懒递归代理,不需要一次性遍历。
优点:
- 可以监听新增/删除属性。
- 可以监听数组的索引、length。
- 性能更优,尤其是大对象。
- 代码更简洁、可维护性高。
对比
| 特性 | Vue 2 (defineProperty) | Vue 3 (Proxy) |
|---|---|---|
| 支持新增属性 | ❌ 需要 Vue.set() | ✅ 自动支持 |
| 数组支持 | ❌ 有限制 | ✅ 完整支持 |
| 性能 | 🐢 深度递归较慢 | 🚀 懒代理性能更好 |
| 兼容性 | ✅ IE9+ 支持 | ❌ IE 不支持 |
| 代理能力 | 只能代理属性 | 可代理整个对象 |