当前位置:首页 > VUE

vue实现响应式原理

2026-01-23 04:00:58VUE

Vue 响应式原理的核心机制

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

Object.defineProperty(Vue 2.x)

vue实现响应式原理

  • 对数据对象的属性进行劫持,通过 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

vue实现响应式原理

  • 每个响应式属性关联一个 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实现mvc

vue实现mvc

Vue 实现 MVC 模式 Vue 本身是一个 MVVM(Model-View-ViewModel)框架,但可以通过结构调整实现 MVC(Model-View-Controller)模式。以下是具体实…

vue实现handsontable

vue实现handsontable

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

vue实现返回

vue实现返回

返回按钮功能实现 在Vue中实现返回功能通常有两种方式:使用浏览器历史记录的history.back()或结合Vue Router进行编程式导航。以下是具体实现方法: 使用浏览器API metho…

vue实现权限

vue实现权限

Vue 实现权限管理的方法 在 Vue 项目中实现权限管理通常涉及路由控制、按钮权限和接口权限。以下是几种常见的实现方式: 路由权限控制 通过动态路由的方式,根据用户权限加载不同的路由配置。可以使用…

vue怎么实现直播

vue怎么实现直播

Vue实现直播的方法 使用Vue实现直播功能通常需要结合第三方直播服务或WebRTC技术。以下是几种常见的实现方式: 使用第三方直播服务 集成如腾讯云、阿里云或七牛云等提供的直播SDK,通过他们的A…

vue实现饼图

vue实现饼图

使用 ECharts 实现 Vue 饼图 安装 ECharts 依赖 npm install echarts --save 在 Vue 组件中引入 ECharts import * as echa…