当前位置:首页 > VUE

vue数据监听具体实现

2026-01-23 02:21:35VUE

Vue 数据监听的具体实现

Vue 的数据监听主要通过 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)实现,核心是依赖收集和派发更新。

Vue 2.x 的实现方式

基于 Object.defineProperty Vue 2.x 使用 Object.defineProperty 对对象的属性进行劫持,通过 getter 和 setter 实现响应式。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      console.log('get', key);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log('set', key);
      val = newVal;
    }
  });
}

依赖收集与派发更新

vue数据监听具体实现

  • 每个响应式属性有一个 Dep 实例,用于存储依赖(Watcher)。
  • 在 getter 中调用 dep.depend() 收集依赖。
  • 在 setter 中调用 dep.notify() 通知依赖更新。
class Dep {
  constructor() {
    this.subs = [];
  }
  depend() {
    if (Dep.target) {
      this.subs.push(Dep.target);
    }
  }
  notify() {
    this.subs.forEach(watcher => watcher.update());
  }
}

Vue 3.x 的实现方式

基于 Proxy Vue 3.x 使用 Proxy 代理整个对象,可以监听动态新增的属性。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      console.log('get', key);
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      console.log('set', key);
      return Reflect.set(target, key, value, receiver);
    }
  });
}

Effect 与依赖追踪 Vue 3.x 引入 effecttrack/trigger 机制:

vue数据监听具体实现

  • track 在 get 时收集依赖。
  • trigger 在 set 时触发更新。
const targetMap = new WeakMap();

function track(target, key) {
  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 dep = depsMap.get(key);
  if (dep) {
    dep.forEach(effect => effect());
  }
}

数组的监听

Vue 2.x 通过重写数组方法(如 pushpop)实现监听:

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);

['push', 'pop', 'shift'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    console.log('array method', method);
    return result;
  };
});

Vue 3.x 的 Proxy 可以直接监听数组变化,无需特殊处理。

总结

  • Vue 2.x 使用 Object.defineProperty 劫持属性,需递归遍历对象,对数组需特殊处理。
  • Vue 3.x 使用 Proxy 代理整个对象,支持动态属性监听,性能更优。
  • 两者均通过依赖收集(Dep/track)和派发更新(notify/trigger)实现响应式。

标签: 具体数据
分享给朋友:

相关文章

vue实现数据翻译

vue实现数据翻译

Vue 实现数据翻译的方法 在 Vue 项目中实现数据翻译(国际化)通常需要结合国际化库或自定义方案。以下是几种常见的方法: 使用 vue-i18n 库 安装 vue-i18n 库: npm…

vue实现表格数据修改

vue实现表格数据修改

实现表格数据修改的基本思路 在Vue中实现表格数据修改通常涉及以下核心步骤:数据绑定、编辑状态切换、表单输入处理和数据提交。以下是一个典型实现方案: 数据绑定与渲染 使用v-for指令循环渲染表格…

vue实现重置表格数据

vue实现重置表格数据

重置表格数据的方法 在Vue中重置表格数据通常涉及清空或重新初始化数据绑定的数组或对象。以下是几种常见实现方式: 直接重置数据源 对于基于数组的表格数据,可以直接将数据数组重置为空或初始值:…

vue实现数据结构图

vue实现数据结构图

Vue 实现数据结构图的方法 使用第三方库 Vue 可以与多种图表库结合使用,例如 D3.js、ECharts 或 Vis.js。这些库提供了强大的图形渲染能力,适合展示复杂的数据结构图。 安装…

Vue数据依赖实现

Vue数据依赖实现

Vue数据依赖实现原理 Vue的数据依赖实现基于响应式系统,核心是通过Object.defineProperty或Proxy拦截数据变化,结合发布-订阅模式实现依赖收集和更新触发。 核心机制 依赖收…

vue实现数据删除

vue实现数据删除

Vue 实现数据删除的方法 在 Vue 中删除数据通常涉及操作数组或对象,并结合响应式更新。以下是几种常见实现方式: 从数组中删除数据 使用 splice 方法删除数组中的指定项: metho…