当前位置:首页 > 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;
    }
  });
}

依赖收集与派发更新

  • 每个响应式属性有一个 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 机制:

  • 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数据监听具体实现

总结

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

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

相关文章

vue实现重置表格数据

vue实现重置表格数据

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

Vue数据依赖实现

Vue数据依赖实现

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

vue  实现数据滚动

vue 实现数据滚动

Vue 实现数据滚动的方法 使用 CSS 动画实现滚动 通过 CSS 的 animation 和 @keyframes 实现滚动效果,适用于简单的文字或数据滚动。 <template>…

vue实现数据过滤

vue实现数据过滤

Vue 数据过滤的实现方法 在 Vue 中实现数据过滤可以通过多种方式,以下是几种常见的实现方法: 使用计算属性(Computed Properties) 计算属性是 Vue 中最常用的数据过滤方式…

vue 实现数据添加

vue 实现数据添加

Vue 数据添加的实现方法 在 Vue 中实现数据添加通常涉及表单绑定、事件处理和状态管理。以下是几种常见场景的实现方式: 表单绑定与提交 通过 v-model 实现表单数据双向绑定,使用 @sub…

vue实现数据多级显示

vue实现数据多级显示

Vue 实现多级数据展示 在 Vue 中实现多级数据展示通常涉及递归组件或嵌套循环。以下是几种常见方法: 递归组件实现 递归组件适合处理不确定层级深度的树形结构数据: <templa…