proxy实现vue
使用 Proxy 实现 Vue 响应式系统
Vue 3 的响应式系统基于 JavaScript 的 Proxy 实现,通过代理对象拦截属性的读取和修改操作,实现数据变化的自动追踪和更新。以下是核心实现方法:
基本响应式实现
通过 Proxy 拦截对象的 get 和 set 操作,结合副作用函数(effect)实现依赖收集和触发更新:

const reactiveMap = new WeakMap();
function reactive(target) {
if (reactiveMap.has(target)) {
return reactiveMap.get(target);
}
const proxy = new Proxy(target, {
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;
}
});
reactiveMap.set(target, proxy);
return proxy;
}
// 当前激活的副作用函数
let activeEffect = null;
function 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);
}
}
function trigger(target, key) {
const depsMap = targetMap.get(target);
if (!depsMap) return;
const effects = depsMap.get(key);
effects && effects.forEach(effect => effect());
}
副作用函数管理
通过 effect 函数注册副作用,在属性被访问时自动建立依赖关系:

const targetMap = new WeakMap();
function effect(fn) {
activeEffect = fn;
fn(); // 执行时会触发 track
activeEffect = null;
}
// 使用示例
const state = reactive({ count: 0 });
effect(() => {
console.log('Count changed:', state.count);
});
state.count++; // 自动触发日志输出
计算属性实现
基于响应式系统和副作用函数,可以实现计算属性:
function computed(getter) {
let value;
let dirty = true;
const runner = effect(getter, {
lazy: true,
scheduler() {
dirty = true;
trigger(obj, 'value');
}
});
const obj = {
get value() {
if (dirty) {
value = runner();
dirty = false;
}
track(obj, 'value');
return value;
}
};
return obj;
}
// 使用示例
const state = reactive({ a: 1, b: 2 });
const sum = computed(() => state.a + state.b);
effect(() => {
console.log('Sum:', sum.value);
});
state.a = 3; // 触发重新计算和日志输出
响应式 Ref 实现
对于基本类型值,可以通过 ref 包装为响应式对象:
function ref(value) {
return reactive({
value
});
}
// 使用示例
const count = ref(0);
effect(() => {
console.log('Ref value:', count.value);
});
count.value++; // 触发更新
注意事项
Proxy无法检测到属性的添加或删除,Vue 3 提供了set和deleteAPI 作为补充- 数组的特殊处理需要额外拦截
push/pop等方法 - 性能优化需要考虑嵌套对象的代理缓存
- 浏览器兼容性需要注意(Proxy 无法被 polyfill)
以上实现展示了 Vue 3 响应式系统的核心原理,实际实现还包含更多优化和边界情况处理。






