当前位置: 首页 > article >正文

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(无需手动处理新增/删除属性)。

http://www.kler.cn/a/407563.html

相关文章:

  • 【SKFramework框架核心模块】3-2、音频管理模块
  • 介绍一下strset(arr,ch);(c基础)
  • PHP实现选择排序
  • Java编程,配置mongoUri连接mongodb时,需对特殊字符进行转义
  • 基于Java Springboot高考志愿填报辅助系统
  • ESP8266 STA模式TCP客户端 电脑手机网络调试助手
  • 线程(三)【线程互斥(下)】
  • 数据结构(初阶6)---二叉树(遍历——递归的艺术)(详解)
  • FIFO架构专题-异步FIFO及信号
  • cookie反爬----普通服务器,阿里系
  • python FastAPI 后台运行
  • git 构建分布式版本控制系统
  • https证书集成到java中
  • C++注释
  • VScode 连不上远程云服务器
  • 通过端口测试验证网络安全策略
  • 开源项目Screenshot-to-Code:截图图片生成代码
  • 大数据-229 离线数仓 - ODS层的构建 Hive处理 JSON 数据处理 结构化
  • Vue3 + Vite 项目引入 postcss + tailwindcss
  • C0029.在Clion中解决Debug时,提示Process finished with exit code -1的错误
  • Altium Designer学习笔记 6-10 异性元件库创建_原理图绘制
  • 【网络安全设备系列】4、漏洞扫描设备
  • 【Git】:Git基本操作
  • QT 关于QTableView的应用和管理
  • 【计算机网络】解决bind error
  • 如何最简单、通俗地理解Python的迭代器?