Vue3 vs Vue2 响应式核心差异#
| 特性 | Vue2 | Vue3 |
|---|---|---|
| 实现方式 | Object.defineProperty | Proxy |
| 拦截范围 | 已有属性 | 整个对象(含新增/删除) |
| 数组支持 | 重写 7 个方法(push/pop等) | 原生支持索引和 length |
| Map/Set | ❌ 不支持 | ✅ 原生支持 |
| 性能 | 初始化递归遍历 | 懒代理(访问时才创建) |
| 兼容性 | IE9+ | 现代浏览器(IE 不支持) |
关键代码对比#
Vue2:递归劫持#
// 初始化时遍历所有属性
function observe(obj) {
Object.keys(obj).forEach(key => {
defineReactive(obj, key, obj[key]);
if (typeof obj[key] === 'object') {
observe(obj[key]); // 递归
}
});
}
// 数组需特殊处理
const arrayMethods = ['push', 'pop', 'splice' /*...*/];
arrayMethods.forEach(method => {
// 重写方法以触发更新
});javascript痛点:新增属性需 Vue.set,数组索引修改检测不到。
Vue3:Proxy 懒代理#
function reactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key); // 依赖收集
const result = Reflect.get(target, key, receiver);
return isObject(result)
? reactive(result) // 懒递归:访问时才代理
: result;
},
set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
trigger(target, key); // 触发更新
return result;
}
// 自动支持 delete、has、ownKeys 等
});
}javascript优势:新增/删除属性自动响应,数组原生支持。