当前位置:首页 > 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 改进

vue实现响应式原理

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

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

相关文章

vue 实现弹幕

vue 实现弹幕

vue 实现弹幕的方法 使用 CSS 动画和动态渲染 在 Vue 中实现弹幕效果,可以通过动态渲染弹幕元素并结合 CSS 动画实现。以下是具体步骤: 数据准备 创建一个数组存储弹幕数据,每条弹幕包…

vue功能实现

vue功能实现

Vue 功能实现指南 Vue.js 是一个渐进式 JavaScript 框架,广泛用于构建用户界面。以下是 Vue 功能的常见实现方法。 数据绑定 Vue 的核心功能之一是数据绑定,通过 v-mod…

vue实现setinterval

vue实现setinterval

在 Vue 中使用 setInterval Vue 中可以通过生命周期钩子和方法结合 setInterval 实现定时任务。以下是一个完整的实现示例: <template> <…

vue实现注册

vue实现注册

Vue 实现注册功能 注册功能通常涉及前端表单、数据验证、与后端 API 的交互等步骤。以下是一个完整的 Vue 实现注册功能的方案。 创建注册表单 使用 Vue 的模板语法创建注册表单,包含用户名…

vue实现select

vue实现select

Vue 实现 Select 组件的方法 在 Vue 中实现 Select 组件可以通过多种方式完成,以下是几种常见的方法: 使用原生 HTML select 元素 原生 HTML 的 <sel…

vue 实现循环

vue 实现循环

Vue 实现循环的方法 在 Vue 中,可以使用 v-for 指令来实现循环渲染列表数据。以下是几种常见的循环实现方式: 基本数组循环 <template> <ul>…