当前位置:首页 > VUE

vue数据响应式实现

2026-01-22 22:33:24VUE

Vue 数据响应式实现原理

Vue 的数据响应式核心是通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现的。以下是具体实现方式:

vue数据响应式实现

Vue 2 的实现

Vue 2 使用 Object.defineProperty 对对象的属性进行劫持,通过 getter 和 setter 监听数据变化。

vue数据响应式实现

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      console.log(`获取 ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log(`设置 ${key}: ${newVal}`);
      val = newVal;
      // 触发视图更新
    }
  });
}

const data = { name: 'Vue' };
defineReactive(data, 'name', data.name);
data.name = 'Vue 2'; // 触发 setter
  • 局限性
    • 无法监听新增或删除的属性(需使用 Vue.setVue.delete)。
    • 对数组的变异方法(如 pushpop)需通过重写实现响应式。

Vue 3 的实现

Vue 3 改用 Proxy 实现响应式,解决了 Vue 2 的局限性。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      console.log(`获取 ${key}: ${target[key]}`);
      return target[key];
    },
    set(target, key, value) {
      if (target[key] === value) return true;
      console.log(`设置 ${key}: ${value}`);
      target[key] = value;
      // 触发视图更新
      return true;
    }
  });
}

const data = reactive({ name: 'Vue' });
data.name = 'Vue 3'; // 触发 setter
  • 优势
    • 直接监听对象而非属性,支持新增和删除属性。
    • 默认支持数组索引和长度的变化。

依赖收集与派发更新

Vue 通过 依赖收集(Dependency Tracking)和 派发更新(Dependency Triggering)实现视图的自动更新。

  1. 依赖收集:在 getter 中收集当前依赖(如组件的渲染函数)。
  2. 派发更新:在 setter 中通知依赖进行更新。
// 简化版的依赖管理
let activeEffect;

class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (activeEffect) this.subscribers.add(activeEffect);
  }
  notify() {
    this.subscribers.forEach(effect => effect());
  }
}

function watchEffect(effect) {
  activeEffect = effect;
  effect();
  activeEffect = null;
}

const dep = new Dep();

const data = reactive({
  count: 0
});

watchEffect(() => {
  console.log(`Count: ${data.count}`); // 触发 getter,收集依赖
});

data.count++; // 触发 setter,通知更新

总结

  • Vue 2:基于 Object.defineProperty,需额外处理数组和新增属性。
  • Vue 3:基于 Proxy,原生支持对象和数组的全面监听。
  • 核心机制:依赖收集(getter)和派发更新(setter)实现数据与视图的同步。

标签: 数据vue
分享给朋友:

相关文章

vue实现目录

vue实现目录

Vue 实现目录功能 在 Vue 中实现目录功能通常需要动态生成目录结构,并支持点击跳转到对应内容区域。以下是几种常见实现方式: 基于滚动监听和动态生成 安装依赖(如需): npm install…

vue的动画实现

vue的动画实现

Vue 动画实现方式 Vue 提供了多种方式实现动画效果,主要通过内置组件和第三方库支持。 使用 Vue 内置过渡组件 Vue 的 transition 和 transition-group 组件可…

vue前端实现打印功能

vue前端实现打印功能

使用Vue实现前端打印功能 在Vue项目中实现打印功能可以通过多种方式完成,以下是几种常见的方法: 使用window.print()方法 这是最简单的打印方式,直接调用浏览器的打印功能。 me…

vue实现展开与收起

vue实现展开与收起

Vue 实现展开与收起功能 在 Vue 中实现展开与收起功能可以通过多种方式完成,以下是一些常见的方法: 使用 v-show 或 v-if 控制显示 通过 Vue 的指令 v-show 或 v-if…

vue实现密码框的包

vue实现密码框的包

Vue 密码框实现方案 在 Vue 中实现密码框功能,可以通过原生 HTML 结合 Vue 指令或使用第三方组件库完成。以下是几种常见方案: 原生 HTML + Vue 双向绑定 <t…

vue实现下拉框删除

vue实现下拉框删除

Vue 实现下拉框删除功能 在Vue中实现下拉框的删除功能通常涉及以下步骤: 数据绑定与渲染 在Vue组件中定义数据数组用于存储下拉框选项: data() { return { op…