当前位置:首页 > 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 的双向数据绑定主要通过 v-model 指令实现,它结合了 v-bind 和 v-on 的功能,能够同步表单输入和应用状态。 基本语法 在表单元素上使用 v-mo…

vue实现数据动态

vue实现数据动态

Vue 实现数据动态绑定的方法 Vue.js 的核心特性之一是数据绑定,通过响应式系统实现数据的动态更新。以下是几种常见的实现方式: 双向数据绑定(v-model) 使用 v-model 指令可以实…

vue实现数据监听

vue实现数据监听

Vue 数据监听实现方式 Vue 提供了多种方式实现数据监听,核心机制基于响应式系统。以下是常见方法: 响应式属性(data 和 computed) 在组件选项中定义 data 返回对象,Vue 会…

vue实现数据交互

vue实现数据交互

Vue 实现数据交互的方法 Vue 提供了多种方式实现数据交互,包括组件通信、状态管理、HTTP 请求等。以下是几种常见的方法: 父子组件通信 父组件通过 props 向子组件传递数据,子组件通过…

vue如何实现数据响应

vue如何实现数据响应

Vue 数据响应的实现原理 Vue 的数据响应式系统基于 ES5 的 Object.defineProperty 或 ES6 的 Proxy 实现。核心是通过数据劫持结合发布-订阅模式,在数据变化时自…

vue怎么实现数据删除

vue怎么实现数据删除

Vue 数据删除的实现方法 在 Vue 中删除数据通常涉及操作数组或对象,以下是几种常见场景的实现方式: 删除数组中的元素 使用 splice 方法删除数组中的特定项: methods: {…