当前位置:首页 > VUE

proxy实现vue

2026-02-10 12:48:15VUE

使用Proxy实现Vue响应式系统

Proxy是ES6引入的特性,能够拦截对象的操作,Vue3利用Proxy替代了Vue2中的Object.defineProperty来实现响应式。以下是实现核心逻辑的方法:

创建响应式对象

function reactive(target) {
  return 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;
    }
  });
}

依赖收集与触发

proxy实现vue

const targetMap = new WeakMap();
let activeEffect = null;

function track(target, key) {
  if (!activeEffect) return;
  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());
}

副作用函数处理

function effect(fn) {
  activeEffect = fn;
  fn();
  activeEffect = null;
}

实现计算属性

基于上述响应式系统,可以扩展实现计算属性:

proxy实现vue

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;
}

实现模板编译

结合Proxy响应式系统,可以模拟Vue的模板编译:

function compile(template) {
  return function render(ctx) {
    const div = document.createElement('div');
    div.innerHTML = template.replace(/{{(.*?)}}/g, (_, exp) => {
      return exp.split('.').reduce((obj, k) => obj[k], ctx);
    });
    return div.firstChild;
  };
}

完整示例组合

将各部分组合成简易Vue实现:

class MiniVue {
  constructor(options) {
    this.$options = options;
    this.$data = reactive(options.data());
    this.proxyData();
    this.$el = document.querySelector(options.el);
    this.compile();
  }

  proxyData() {
    for (const key in this.$data) {
      Object.defineProperty(this, key, {
        get: () => this.$data[key],
        set: val => (this.$data[key] = val)
      });
    }
  }

  compile() {
    const render = compile(this.$options.template);
    effect(() => {
      const newNode = render(this.$data);
      this.$el.innerHTML = '';
      this.$el.appendChild(newNode);
    });
  }
}

注意事项

Proxy相比Object.defineProperty的优势在于能检测到新增属性、数组索引变化等,但需要注意以下问题:

  • 浏览器兼容性:Proxy无法被polyfill
  • 性能考虑:嵌套对象的处理需要递归代理
  • 原始值处理:需要额外包装为对象才能被代理

这种实现展示了Vue响应式原理的核心思想,实际Vue3的实现还包含更多优化和边界情况处理。

标签: proxyvue
分享给朋友:

相关文章

vue 实现pdf

vue 实现pdf

在Vue中实现PDF功能 在Vue项目中实现PDF功能通常涉及PDF生成、预览或下载。以下是几种常见实现方式: 使用vue-pdf库预览PDF 安装依赖: npm install vue-…

vue权限实现

vue权限实现

Vue 权限实现方案 基于路由的权限控制 通过路由守卫实现权限验证,在路由配置中添加meta字段标记权限要求。在router.beforeEach中检查用户权限与路由要求的匹配情况。 // rout…

vue实现通知

vue实现通知

Vue 实现通知功能的方法 使用 Vue 实现通知功能可以通过多种方式实现,以下是一些常见的方法: 使用 Vue 的全局事件总线 在 Vue 中可以通过事件总线实现通知功能。创建一个全局事件总线,然…

vue实现定位

vue实现定位

Vue 中实现定位的方法 在 Vue 中实现定位可以通过以下几种方式: 使用 CSS 定位 通过 CSS 的 position 属性实现定位,Vue 中可以直接在组件的 <style>…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

利用vue 实现

利用vue 实现

以下是利用 Vue 实现常见功能的几种方法,分为不同场景和技术要点: 数据绑定与响应式更新 Vue 的核心特性是数据绑定,通过 v-model 实现双向绑定: <template>…