当前位置:首页 > VUE

proxy实现vue

2026-03-07 12:38:16VUE

使用 Proxy 实现 Vue 响应式系统

Vue 3 的响应式系统基于 JavaScript 的 Proxy 实现,通过代理对象拦截属性的读取和修改操作,实现数据变化的自动追踪和更新。以下是核心实现方法:

基本响应式实现

通过 Proxy 拦截对象的 getset 操作,结合副作用函数(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 包装为响应式对象:

proxy实现vue

function ref(value) {
  return reactive({
    value
  });
}

// 使用示例
const count = ref(0);

effect(() => {
  console.log('Ref value:', count.value);
});

count.value++; // 触发更新

注意事项

  1. Proxy 无法检测到属性的添加或删除,Vue 3 提供了 setdelete API 作为补充
  2. 数组的特殊处理需要额外拦截 push/pop 等方法
  3. 性能优化需要考虑嵌套对象的代理缓存
  4. 浏览器兼容性需要注意(Proxy 无法被 polyfill)

以上实现展示了 Vue 3 响应式系统的核心原理,实际实现还包含更多优化和边界情况处理。

标签: proxyvue
分享给朋友:

相关文章

vue实现展开与收起

vue实现展开与收起

Vue 实现展开与收起功能 在 Vue 中实现展开与收起功能可以通过多种方式完成,以下是一些常见的方法: 使用 v-show 或 v-if 控制显示 通过 Vue 的指令 v-show 或 v-if…

vue实现计时

vue实现计时

Vue 实现计时功能 在 Vue 中实现计时功能可以通过多种方式完成,以下是几种常见的方法: 使用 setInterval 实现基础计时器 通过 setInterval 和 clearInterva…

vue 实现音乐

vue 实现音乐

Vue 实现音乐播放功能 在 Vue 中实现音乐播放功能,可以通过 HTML5 的 <audio> 元素或第三方库如 howler.js 来实现。以下是两种方法的详细步骤: 使用 HTM…

vue实现幻灯

vue实现幻灯

Vue实现幻灯片的基础方法 使用Vue实现幻灯片功能可以通过多种方式完成,以下是几种常见方案: 方案一:基于Vue的过渡动画 通过Vue的<transition>或<transit…

vue实现反转

vue实现反转

实现数组反转 在Vue中反转数组可以通过多种方式实现,以下是几种常见方法: 使用JavaScript原生reverse方法 // 在methods中定义方法 methods: { revers…

vue如何实现排序

vue如何实现排序

实现数组排序 在Vue中实现数组排序可以通过computed属性或methods来处理。假设有一个数组items,可以创建一个计算属性返回排序后的数组: data() { return {…