当前位置:首页 > 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 实现拖动数据的方法 使用 HTML5 拖放 API HTML5 提供了原生的拖放 API,可以通过 draggable 属性和相关事件实现拖动功能。 <template>…

vue实现数据拖动

vue实现数据拖动

Vue 实现数据拖动 在 Vue 中实现数据拖动通常涉及 HTML5 的拖放 API 或第三方库(如 vuedraggable)。以下是两种常见方法: 使用 HTML5 拖放 API 设置拖拽元…

vue实现数据

vue实现数据

Vue 数据绑定与状态管理 在 Vue 中,数据绑定和状态管理是核心功能,主要通过响应式系统、组件通信和状态管理库实现。 响应式数据绑定 Vue 使用 data 选项声明响应式数据,数据变更会自动触…

uniapp 数据

uniapp 数据

uniapp 数据管理方法 本地存储 使用 uni.setStorageSync 和 uni.getStorageSync 进行本地数据持久化存储。适合保存用户偏好设置或小型数据。 // 存储数…

vue实现数据删除

vue实现数据删除

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

vue怎么实现数据

vue怎么实现数据

Vue 数据实现方式 Vue 提供了多种方式来实现数据的响应式绑定和管理,核心是通过数据驱动视图的更新。 响应式数据声明 在 Vue 组件中,可以通过 data 选项声明响应式数据。这些数据会被…