Vue2 vs Vue3 响应式原理对比
今天来聊聊 Vue2 和 Vue3 的响应式原理,看看它们到底有啥不同!👀
无论是面试还是实战,掌握响应式原理都是 Vue 开发的必备技能哦!
Vue2 的响应式原理
Vue2 的响应式是通过 Object.defineProperty 实现的。
实现步骤:
- 数据劫持:
-
- 使用
Object.defineProperty对对象的每个属性进行劫持。 - 当属性被读取时,触发
getter,收集依赖(Watcher)。 - 当属性被修改时,触发
setter,通知依赖更新。
- 使用
- 依赖收集:
-
- 每个属性都有一个依赖列表(Dep),用于存储 Watcher。
- 当数据变化时,Dep 会通知所有 Watcher 更新视图。
- 数组处理:
-
- Vue2 对数组的响应式是通过重写数组的 7 个方法(如
push、pop、splice等)实现的。
- Vue2 对数组的响应式是通过重写数组的 7 个方法(如
代码示例:
function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖列表
Object.defineProperty(obj, key, {
get() {
dep.depend(); // 收集依赖
return val;
},
set(newVal) {
val = newVal;
dep.notify(); // 通知依赖更新
},
});
}
缺点:
- 无法监听新增/删除属性:需要使用
Vue.set或Vue.delete。 - 数组响应式有限:只能通过重写方法实现,无法监听索引或长度变化。
Vue3 的响应式原理
Vue3 的响应式是通过 Proxy 实现的。
实现步骤:
- 数据劫持:
-
- 使用
Proxy对整个对象进行代理。 - 当对象被读取或修改时,触发
get和set拦截器。
- 使用
- 依赖收集:
-
- 通过
track函数收集依赖(Effect)。 - 通过
trigger函数通知依赖更新。
- 通过
- 数组处理:
-
- Proxy 可以直接监听数组的索引和长度变化,无需特殊处理。
代码示例:
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
track(target, key); // 收集依赖
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver);
trigger(target, key); // 通知依赖更新
return true;
},
});
}
优点:
- 全面监听:可以监听新增/删除属性,以及数组的索引和长度变化。
- 性能更好:Proxy 是原生支持的特性,性能优于
Object.defineProperty。 - 代码更简洁:无需特殊处理数组和对象。
📊 Vue2 和 Vue3 响应式对比表
| 特性 | Vue2 | Vue3 |
|---|---|---|
| 实现方式 | Object.defineProperty | Proxy |
| 监听对象 | 对象的属性 | 整个对象 |
| 监听数组 | 重写数组方法 | 直接监听索引和长度 |
| 新增/删除属性 | 不支持(需 Vue.set/Vue.delete) | 支持 |
| 性能 | 较低 | 较高 |
| 代码复杂度 | 较高 | 较低 |
总结
- Vue2:通过
Object.defineProperty实现响应式,功能有限,性能较低。 - Vue3:通过
Proxy实现响应式,功能强大,性能更好。
Vue3 的响应式设计更加现代化,尤其是对数组和对象的全面监听,让开发更加高效!快来试试 Vue3 的新特性吧!