proxy实现vue
使用 Proxy 实现 Vue 响应式系统
Proxy 是 ES6 提供的一种机制,可以拦截对象的操作。Vue 3 使用 Proxy 替代了 Vue 2 的 Object.defineProperty,实现更强大的响应式功能。
基本 Proxy 实现响应式
通过 Proxy 拦截对象的读取和设置操作,结合依赖收集和触发更新机制,可以实现简单的响应式系统。
const reactive = (target) => {
const handler = {
get(target, key, receiver) {
track(target, key);
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
const oldValue = target[key];
const result = Reflect.set(target, key, value, receiver);
if (oldValue !== value) {
trigger(target, key);
}
return result;
}
};
return new Proxy(target, handler);
};
// 依赖收集
const targetMap = new WeakMap();
let activeEffect = null;
const track = (target, key) => {
if (activeEffect) {
let depsMap = targetMap.get(target);
if (!depsMap) {
targetMap.set(target, (depsMap = new Map()));
}
let dep = depsMap.get(key);
if (!dep) {
depsMap.set(key, (dep = new Set()));
}
dep.add(activeEffect);
}
};
// 触发更新
const trigger = (target, key) => {
const depsMap = targetMap.get(target);
if (!depsMap) return;
const effects = depsMap.get(key);
effects && effects.forEach(effect => effect());
};
// 副作用函数
const effect = (fn) => {
activeEffect = fn;
fn();
activeEffect = null;
};
使用示例
const state = reactive({
count: 0
});
effect(() => {
console.log(`count changed: ${state.count}`);
});
state.count++; // 输出 "count changed: 1"
state.count = 5; // 输出 "count changed: 5"
处理嵌套对象
Proxy 默认只代理第一层属性,需要递归处理嵌套对象:
const reactive = (target) => {
const handler = {
get(target, key, receiver) {
track(target, key);
const value = Reflect.get(target, key, receiver);
return typeof value === 'object' ? reactive(value) : value;
},
// ...其他拦截器
};
return new Proxy(target, handler);
};
处理数组
Proxy 可以很好地处理数组操作,包括 push、pop 等方法:
const handler = {
get(target, key, receiver) {
track(target, key);
const value = Reflect.get(target, key, receiver);
// 处理数组方法
if (Array.isArray(target) && ['push', 'pop', 'shift', 'unshift', 'splice'].includes(key)) {
return (...args) => {
const result = Array.prototype[key].apply(target, args);
trigger(target, 'length');
return result;
};
}
return typeof value === 'object' ? reactive(value) : value;
},
// ...其他拦截器
};
与 Vue 3 的对比
Vue 3 的响应式系统实现更复杂,包含以下额外功能:
- 更完善的依赖清理机制
- 性能优化(避免不必要的触发)
- 支持 Map、Set 等集合类型
- 提供 ref、computed 等响应式API
性能注意事项
- Proxy 比 Object.defineProperty 性能更好
- 嵌套对象的深度代理会增加内存开销
- 频繁的小规模更新可能触发多次渲染
浏览器兼容性
Proxy 是 ES6 特性,不支持 IE11 及更早版本。如果需要支持旧浏览器,需要使用 polyfill 或回退到 Vue 2 的实现方式。







