当前位置:首页 > VUE

vue监听实现原理

2026-02-18 11:51:56VUE

Vue 监听实现原理

Vue 的监听机制主要通过 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)实现数据响应式。以下是核心原理的详细分析:

vue监听实现原理

数据劫持(Vue 2.x)

Vue 2.x 使用 Object.defineProperty 劫持对象的属性访问和修改。通过为每个属性设置 gettersetter,在数据变化时触发依赖更新。

vue监听实现原理

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('读取属性', key);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log('更新属性', key);
        val = newVal;
        // 触发依赖更新
        dep.notify();
      }
    }
  });
}
  • 依赖收集:在 getter 中,当前正在执行的 Watcher(如组件渲染函数)会被添加到依赖列表(Dep)中。
  • 派发更新:在 setter 中,通知所有依赖的 Watcher 执行更新。

代理模式(Vue 3.x)

Vue 3.x 改用 Proxy 实现更强大的响应式能力。Proxy 可以直接监听整个对象而非属性,并支持动态新增属性的监听。

const 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;
    }
  });
};
  • 优势:无需递归遍历对象属性,性能更好;支持监听数组索引和 length 变化。

依赖管理

  • Dep 类:每个响应式属性对应一个 Dep 实例,用于存储所有依赖的 Watcher
  • Watcher 类:代表一个依赖(如组件渲染函数、计算属性),在数据变化时执行回调。
class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (activeWatcher) this.subscribers.add(activeWatcher);
  }
  notify() {
    this.subscribers.forEach(watcher => watcher.update());
  }
}

数组监听的特殊处理

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);
    dep.notify(); // 手动触发更新
    return result;
  };
});

总结

  • Vue 2.x 基于 Object.defineProperty,需显式声明响应式属性,对数组需特殊处理。
  • Vue 3.x 基于 Proxy,支持全对象监听,性能更优,代码更简洁。
  • 依赖收集和派发更新通过 DepWatcher 协作完成。

标签: 原理vue
分享给朋友:

相关文章

vue实现预览

vue实现预览

Vue实现文件预览的方法 使用Vue实现文件预览功能可以通过多种方式完成,具体取决于文件类型(图片、PDF、视频等)。以下是几种常见文件类型的实现方案。 图片预览 通过<input type=…

vue 实现pdf

vue 实现pdf

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

vue实现handsontable

vue实现handsontable

Vue 中实现 Handsontable 要在 Vue 项目中集成 Handsontable,可以使用官方提供的 @handsontable/vue 封装库。以下是一个完整的实现步骤。 安装依赖 确…

vue实现定时

vue实现定时

Vue 实现定时功能的方法 使用 setInterval 和 clearInterval 在 Vue 中可以通过 setInterval 和 clearInterval 实现定时功能。在组件的 mou…

vue实现分步

vue实现分步

Vue 实现分步功能 在 Vue 中实现分步功能可以通过多种方式完成,以下是几种常见的方法: 使用动态组件 通过动态组件切换不同的步骤内容,结合 v-if 或 component 标签实现分步逻辑。…

原生实现vue功能

原生实现vue功能

原生JavaScript实现Vue核心功能 使用原生JavaScript模拟Vue的核心功能需要理解响应式数据绑定、虚拟DOM和组件系统等概念。以下是关键实现方法: 响应式数据系统 通过Object…