当前位置:首页 > VUE

vue实现响应式原理

2026-01-23 04:00:58VUE

Vue 响应式原理的核心机制

Vue 的响应式系统基于 数据劫持依赖收集,通过以下机制实现:

Object.defineProperty(Vue 2.x)

  • 对数据对象的属性进行劫持,通过 gettersetter 拦截读写操作。
  • getter 中收集依赖(Watcher),setter 中触发更新。
// 简化版数据劫持示例
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('收集依赖');
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log('触发更新');
        val = newVal;
      }
    }
  });
}

Proxy(Vue 3.x)

  • 使用 ES6 的 Proxy 代理整个对象,支持动态新增属性监听。
  • 通过 getset 陷阱函数实现依赖收集和触发更新。
// 简化版 Proxy 示例
const reactive = (target) => {
  return new Proxy(target, {
    get(target, key) {
      console.log('收集依赖');
      return target[key];
    },
    set(target, key, value) {
      if (target[key] !== value) {
        console.log('触发更新');
        target[key] = value;
      }
      return true;
    }
  });
};

依赖收集与派发更新

Watcher 和 Dep

  • 每个响应式属性关联一个 Dep(依赖管理器),用于存储依赖的 Watcher
  • 组件渲染时创建 Watcher,触发 getterWatcher 添加到 Dep 中。
  • 数据变化时通过 setter 通知 Dep,执行所有 Watcher 的更新逻辑。
class Dep {
  constructor() {
    this.subscribers = [];
  }
  depend() {
    if (target && !this.subscribers.includes(target)) {
      this.subscribers.push(target);
    }
  }
  notify() {
    this.subscribers.forEach(sub => sub());
  }
}

异步更新队列

  • 多次数据修改会合并为一次更新,通过 nextTick 实现异步批量处理。
  • 避免频繁 DOM 操作,提升性能。
// 简化版异步更新
let queue = [];
let flushing = false;
function queueWatcher(watcher) {
  if (!flushing) {
    queue.push(watcher);
    nextTick(flushQueue);
  }
}
function flushQueue() {
  flushing = true;
  queue.forEach(watcher => watcher.run());
  queue = [];
  flushing = false;
}

数组响应式处理

  • 重写数组的 pushpop 等变异方法,在调用时触发更新。
  • Vue 2.x 通过原型链拦截实现,Vue 3.x 的 Proxy 天然支持。
// Vue 2.x 数组劫持示例
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop'].forEach(method => {
  arrayMethods[method] = function() {
    const result = arrayProto[method].apply(this, arguments);
    dep.notify(); // 手动触发更新
    return result;
  };
});

总结对比

Vue 2.x 限制

  • 无法检测对象属性的添加/删除(需用 Vue.set/Vue.delete)。
  • 数组需通过变异方法触发更新。

Vue 3.x 改进

  • Proxy 支持全对象监听,包括动态属性。
  • 性能优化,减少递归劫持的开销。

vue实现响应式原理

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

相关文章

vue路由实现内部切换

vue路由实现内部切换

Vue 路由实现内部切换的方法 Vue Router 是 Vue.js 官方的路由管理器,用于实现单页应用(SPA)的页面切换。以下是几种常见的内部路由切换方式: 使用 <router-li…

vue实现一个系统

vue实现一个系统

Vue 系统实现步骤 项目初始化与配置 使用 Vue CLI 或 Vite 创建项目: npm init vue@latest my-system 选择需要的配置(Router、Pinia 等)。…

vue实现下拉刷新组件

vue实现下拉刷新组件

实现下拉刷新组件的核心思路 下拉刷新功能通常通过监听触摸事件、滚动位置和动画效果实现。Vue中可以利用自定义指令或封装组件完成,以下为两种常见实现方式。 基于自定义指令的实现 创建指令监听触摸事件…

vue实现缩放

vue实现缩放

Vue 实现缩放的方法 在 Vue 中实现缩放功能可以通过多种方式完成,以下是一些常见的方法: 使用 CSS transform 属性 通过 CSS 的 transform: scale() 属性可…

vue实现同步

vue实现同步

Vue 实现同步的方法 在 Vue 中实现同步操作通常涉及数据绑定、状态管理和异步操作的处理。以下是几种常见的方法: 使用计算属性(Computed Properties) 计算属性基于响应式依赖进…

vue router 实现

vue router 实现

Vue Router 的实现 Vue Router 是 Vue.js 的官方路由管理器,用于构建单页面应用(SPA)。以下是 Vue Router 的核心实现方式。 安装 Vue Router 通…