当前位置:首页 > VUE

vue响应式实现

2026-03-26 17:55:55VUE

Vue 响应式实现原理

Vue 的响应式系统基于 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现,核心是通过数据劫持和依赖收集机制自动追踪数据变化并触发视图更新。

数据劫持

在 Vue 2 中,通过 Object.defineProperty 递归遍历对象的属性,将其转换为 getter/setter:

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;
      }
    }
  });
}

在 Vue 3 中,使用 Proxy 代理整个对象,无需递归遍历:

vue响应式实现

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      console.log(`读取 ${key}`);
      return target[key];
    },
    set(target, key, newVal) {
      if (target[key] !== newVal) {
        console.log(`设置 ${key}`);
        target[key] = newVal;
      }
      return true;
    }
  });
}

依赖收集与派发更新

Vue 通过依赖收集(Dependency Tracking)建立数据与视图的关联:

  1. Watcher:每个组件实例对应一个 Watcher,负责监听数据变化并触发更新。
  2. Dep:每个响应式属性关联一个 Dep(依赖管理器),用于存储所有依赖该属性的 Watcher。

当数据被读取时,触发 getter 并将当前 Watcher 添加到 Dep 中:

vue响应式实现

get() {
  if (Dep.target) { // 当前 Watcher
    dep.addSub(Dep.target); // 收集依赖
  }
  return val;
}

当数据被修改时,触发 setter 并通知所有关联的 Watcher 更新:

set(newVal) {
  val = newVal;
  dep.notify(); // 通知所有 Watcher
}

数组响应式处理

Vue 对数组方法(如 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;
  };
});

性能优化

  1. 异步更新队列:Vue 将多次数据变化合并为一次更新,通过 nextTick 实现批量 DOM 渲染。
  2. 虚拟 DOM:通过 Diff 算法最小化 DOM 操作,提升渲染效率。

总结

Vue 响应式系统的核心是通过数据劫持和依赖收集实现自动更新。Vue 2 使用 Object.defineProperty,Vue 3 升级为 Proxy,解决了深层嵌套和数组监听的问题,同时优化了性能。

标签: vue
分享给朋友:

相关文章

vue实现picker

vue实现picker

Vue 实现 Picker 组件的方法 在 Vue 中实现 Picker 组件可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 HTML 和 CSS 实现 通过 Vue 的模板和样式绑定,…

vue 组件实现

vue 组件实现

Vue 组件实现方法 单文件组件 (SFC) 使用 .vue 文件格式,包含模板、脚本和样式三部分: <template> <div class="example">{{…

vue实现上传

vue实现上传

Vue 文件上传实现方法 使用 Vue 实现文件上传可以通过原生 HTML5 的 <input type="file"> 元素结合 Vue 的事件处理和数据绑定来实现。 基础实现步骤…

vue实现拖动

vue实现拖动

Vue实现拖动的常用方法 在Vue中实现拖动功能通常需要结合HTML5的拖放API或第三方库。以下是几种常见实现方式: 使用HTML5原生拖放API HTML5提供了原生拖放API,可以通过drag…

vue实现横滚

vue实现横滚

Vue 实现横滚效果 横滚效果通常指水平滚动内容,常见于轮播图、横向导航栏等场景。以下是几种实现方式: 使用 CSS 和 Vue 结合 通过 CSS 的 overflow-x 和 white-spa…

实现vue message

实现vue message

实现 Vue 消息提示组件 创建 Message 组件 在 src/components 目录下创建 Message.vue 文件,内容如下: <template> <tran…