自学内容网 自学内容网

Vue3响应式原理

Vue 3 的响应式系统基于 Proxy 对象实现,具有更高的性能和灵活性,相比 Vue 2 使用的 Object.defineProperty 有明显的改进。以下是 Vue 3 响应式原理的关键部分:


1. 核心机制

Vue 3 响应式系统的核心是 reactive API,它使用 Proxy 拦截对对象的访问和修改,从而实现数据的追踪和更新。

1.1 reactive 的实现
import { reactive } from 'vue';

const state = reactive({
  count: 0,
  info: {
    name: 'Vue',
    version: 3
  }
});

在上述代码中:

  • reactive 会将传入的普通对象转换为响应式对象。
  • Vue 通过 Proxy 拦截对对象的操作(如 getset),从而实现依赖收集和变化通知。

1.2 依赖收集与追踪

响应式系统的工作过程可以分为以下几步:

  1. 依赖收集:当某个响应式属性被访问时,Vue 会记录哪个组件或函数依赖了该属性。
  2. 触发更新:当响应式属性的值发生变化时,Vue 通知所有依赖该属性的函数重新执行。

依赖收集是通过 Effect 函数 实现的:

import { effect } from 'vue';

effect(() => {
  console.log(state.count);
});

在执行 effect 时,Vue 会自动订阅 state.count,因此当 state.count 的值发生变化时,该 effect 会重新运行。


2. Proxy 的核心拦截点

Vue 3 的响应式系统通过 Proxy 提供的拦截机制,完成以下操作:

2.1 get:读取属性

当访问对象的属性时,Vue 会触发 get 拦截器,从而完成依赖收集:

const handler = {
  get(target, key, receiver) {
    const result = Reflect.get(target, key, receiver);
    console.log(`读取属性 ${key}: ${result}`);
    return result;
  }
};
2.2 set:修改属性

当修改对象的属性时,Vue 会触发 set 拦截器,从而通知依赖更新:

const handler = {
  set(target, key, value, receiver) {
    const result = Reflect.set(target, key, value, receiver);
    console.log(`设置属性 ${key}: ${value}`);
    // 触发依赖更新
    return result;
  }
};
2.3 tracktrigger

Vue 3 将依赖追踪和触发分成了两个步骤:

  • track:在 get 中调用,用于记录依赖。
  • trigger:在 set 中调用,用于通知依赖更新。

3. 响应式工具

Vue 3 提供了一些内置工具和方法,帮助开发者处理响应式对象。

3.1 reactiveref
  • reactive:将对象或数组转换为响应式对象。
  • ref:用于包装单个值,使其具有响应式能力。
import { ref } from 'vue';

const count = ref(0);

effect(() => {
  console.log(count.value); // 监听 count 的变化
});
count.value++; // 触发更新
3.2 computed
  • computed 用于创建基于响应式数据的派生状态,并具有缓存功能。
import { computed } from 'vue';

const doubled = computed(() => count.value * 2);
console.log(doubled.value); // 自动计算并缓存结果

4. 与 Vue 2 的对比

特性Vue 2 (Object.defineProperty)Vue 3 (Proxy)
支持的数据类型仅支持对象和数组支持对象、数组、Map、Set 等多种类型
深度响应式初始化时递归遍历对象按需追踪,性能更优
新增/删除属性响应式需要 Vue.setVue.delete原生支持
性能初始化开销较大,动态追踪效率低初始化开销小,动态追踪效率高

5. 总结

Vue 3 的响应式系统使用 Proxy 和优化的依赖追踪机制(tracktrigger),实现了:

  1. 更灵活的响应式能力(支持 Map、Set 等)。
  2. 更高的性能(按需追踪,避免冗余计算)。
  3. 更简洁的 API(无需手动处理新增/删除属性)。

原文地址:https://blog.csdn.net/gklcsdn/article/details/143989787

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!