Vue3响应式原理解析

一、什么是响应式?

想象一个 Excel 表格:当单元格 A1 的值变化时,依赖 A1 的公式(如 SUM(A1, B1))会自动重新计算。Vue3 的响应式系统正是实现了这种“自动更新”的能力——当数据变化时,依赖它的视图或计算属性会自动更新。


二、Vue3 响应式的核心实现

1. 底层工具:Proxy 与 Reflect

Vue3 使用 Proxy 代替 Vue2 的 Object.defineProperty,因为它能拦截对象的所有操作(如属性读取、新增、删除等),而无需预先定义属性149。

const obj = { a: 1 };
const proxy = new Proxy(obj, {
  get(target, key) {
    console.log('读取属性:', key);
    return Reflect.get(target, key); // 使用 Reflect 保证 this 指向正确
  },
  set(target, key, value) {
    console.log('设置属性:', key, value);
    return Reflect.set(target, key, value);
  }
});

2. 响应式对象:reactive()

reactive() 函数将普通对象转为响应式对象,内部通过 Proxy 实现:

function reactive(target) {
  return new Proxy(target, {
    get(target, key) {
      track(target, key); // 收集依赖
      const res = Reflect.get(target, key);
      // 递归处理嵌套对象
      return isObject(res) ? reactive(res) : res;
    },
    set(target, key, value) {
      Reflect.set(target, key, value);
      trigger(target, key); // 触发更新
      return true;
    }
  });
}

关键点

  • 深层响应:嵌套对象会被递归代理1。

  • 避免重复代理:通过 WeakMap 缓存已代理对象10。


3. 副作用函数:effect()

副作用函数(如渲染函数)会在依赖的响应式数据变化时重新执行:

let activeEffect;
function effect(fn) {
  const _effect = () => {
    activeEffect = _effect; // 标记当前正在执行的副作用函数
    fn();
    activeEffect = null;
  };
  _effect(); // 立即执行一次以收集依赖
}

// 示例
effect(() => {
  console.log('数据变化了:', state.a);
});

4. 依赖收集与触发更新

(1) 数据结构
  • targetMapWeakMap,键为响应式对象,值为 depsMap

  • depsMapMap,键为对象的属性名,值为 dep(依赖集合)。

  • depSet,存储所有依赖该属性的副作用函数210。

(2) track():收集依赖

在读取属性时,将当前副作用函数加入依赖集合:

const targetMap = new WeakMap();
function track(target, key) {
  if (!activeEffect) return;
  let depsMap = targetMap.get(target);
  if (!depsMap) targetMap.set(target, (depsMap = new Map()));
  let dep = depsMap.get(key);
  if (!dep) depsMap.set(key, (dep = new Set()));
  dep.add(activeEffect);
}
(3) trigger():触发更新

在设置属性时,执行所有依赖该属性的副作用函数:

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  const dep = depsMap.get(key);
  dep && dep.forEach(effect => effect());
}

三、Vue3 对比 Vue2 的优势49

特性Vue2 (Object.defineProperty)Vue3 (Proxy)
检测新增属性需手动调用 Vue.set()自动支持
数组索引修改需重写数组方法直接通过下标修改即可
嵌套对象处理需递归初始化按需代理(惰性处理)
性能初始化时递归遍历所有属性动态代理,按需收集依赖

四、实战示例

1. 基础响应式

const state = reactive({ count: 0 });
effect(() => {
  console.log('count 值变为:', state.count);
});
state.count++; // 触发控制台输出

2. 嵌套对象

const obj = reactive({ 
  foo: { bar: 1 } 
});
effect(() => {
  console.log(obj.foo.bar); // 深层属性仍可响应
});
obj.foo.bar = 2; // 触发更新

五、总结

Vue3 的响应式系统通过 Proxy 拦截对象操作,结合 依赖收集(track) 与 触发更新(trigger) 实现了高效的数据绑定。相比 Vue2,它解决了动态属性、数组操作等痛点,且性能更优。理解其核心原理有助于更好地使用 Vue3 开发复杂应用。

想深入学习可参考:Vue3 响应式官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980086.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HBuilderx 插件开发变量名称翻译 ,中文转(小驼峰,大驼峰,下划线,常量,CSS类名)

HBuilderx 插件开发变量名称翻译 ,中文转(小驼峰,大驼峰,下划线,常量,CSS类名) 插件开发文档 工具HBuilderx ,创建项目 创建成功后目录 插件需求 开发时 用来将中文转为&#xff0…

C# 数据转换

1. 文本框读取byte,ushort格式数据 byte addr; if (byte.TryParse(textBoxAddr.Text, out addr) true) {}2. 字节数组 (byte[]) 转换为 ASCII 字符串 byte[] bytes { 72, 101, 108, 108, 111 }; // "Hello" 的 ASCII 码 string s0 Encoding.ASCII.Ge…

unity学习60: 滑动条 和 滚动条 滚动区域

目录 1 滚动条 scrollbar 1.1 创建滚动条 1.2 scrollbar的子物体 1.3 scrollbar的属性 2 滚动视图 scroll View 2.1 创建1个scroll View 2.1.1 实际类比,网页就是一个 scroll view吧 2.2 子物体构成 2.3 核心component : Scroll Rect 3 可视区域 view p…

如何通过 LlamaIndex 将数据导入 Elasticsearch

作者:来自 Elastic Andre Luiz 逐步介绍如何使用 RAG 和 LlamaIndex 提取数据并进行搜索。 在本文中,我们将使用 LlamaIndex 来索引数据,从而实现一个常见问题搜索引擎。 Elasticsearch 将作为我们的向量数据库,实现向量搜索&am…

从黑暗到光明:FPC让盲人辅助眼镜成为视障者的生活明灯!【新立电子】

在科技日新月异的今天,智能技术正以前所未有的方式改变着我们的生活。对于视障人士而言,科技的进步更是为他们打开了一扇通往更加独立自主生活的大门。其中,盲人辅助智能眼镜可以成为视障人士日常生活中的得力助手。FPC在AR眼镜中的应用&…

【MySQL】数据类型与表约束

目录 数据类型分类 数值类型 tinyint类型 bit类型 小数类型 字符串类型 日期和时间类型 enum和set 表的约束 空属性 默认值 列描述 zerofill 主键 自增长 唯一键 外键 数据类型分类 数值类型 tinyint类型 MySQL中,整形可以是有符号和无符号的&…

tableau之标靶图、甘特图和瀑布图

一、标靶图 概念 标靶图(Bullet Chart)是一种用于显示数据与目标之间关系的可视化图表,常用于业务和管理报告中。其设计旨在用来比较实际值与目标值,同时展示额外的上下文信息(如趋势)。 作用 可视化目标…

微服务学习(2):实现SpringAMQP对RabbitMQ的消息收发

目录 SpringAMQP是什么 为什么采用SpringAMQP SpringAMQP应用 准备springBoot工程 实现消息发送 SpringAMQP是什么 Spring AMQP是Spring框架下用于简化AMQP(高级消息队列协议)应用开发的一套工具集,主要针对RabbitMQ等消息中间件的集成…

【JAVA SE基础】抽象类和接口

目录 一、前言 二、抽象类 2.1 抽象类的概念 2.2 抽象类语法 2.3 抽象类特性 2.4 抽象类的作用 三、接口 3.1 什么是接口 3.2 语法规则 3.3 接口使用 3.4 接口特性 3.5 实现多接口 3.6 接口间的继承 四、Object类 4.1 获取对象信息( toString() &…

《每天读一个JDK源码》之HashMap解读

📌《每天读一个JDK源码》之HashMap解读 🔗源码定位:java.util.HashMap(建议IDE对照阅读) 今天我们来破解Java集合框架中最精妙的艺术品——HashMap!它不仅是面试必考题(出现率99%)&…

蓝牙接近开关模块感应开锁手机靠近解锁支持HID低功耗

ANS-BT101M是安朔科技推出的蓝牙接近开关模块,低功耗ble5.1,采用UART通信接口,实现手机自动无感连接,无需APP,人靠近车门自动开锁,支持苹果、安卓、鸿蒙系统,也可以通过手机手动开锁或上锁&…

[STM32]从零开始的STM32 BSRR、BRR、ODR寄存器讲解

一、前言 学习STM32一阵子以后,相信大家对STM32 GPIO的控制也有一定的了解了。之前在STM32 LED的教程中也教了大家如何使用寄存器以及库函数控制STM32的引脚从而点亮一个LED,之前的寄存器只是作为一个引入,并没有深层次的讲解,在教…

Linux下的网络通信编程

在不同主机之间,进行进程间的通信。 1解决主机之间硬件的互通 2.解决主机之间软件的互通. 3.IP地址:来区分不同的主机(软件地址) 4.MAC地址:硬件地址 5.端口号:区分同一主机上的不同应用进程 网络协议…

C#高级:结合Linq的SelectMany方法实现笛卡尔积效果

一、笛卡尔积定义 又称直积&#xff0c;表示为X Y&#xff0c;第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员 二、基础示例 class Program {static void Main(string[] args){try{List<List<string>> input new List<List<string&g…

通信原理速成笔记(信息论及编码)

信息论基础 信息的定义与度量 信息是用来消除不确定性的内容。例如&#xff0c;在猜硬币正反的情境中&#xff0c;结果存在正反两种不确定性&#xff0c;而得知正确结果能消除这种不确定性&#xff0c;此结果即为信息。单个事件的信息量&#xff1a;对于离散信源中的事件xi​&…

MySQL实现文档全文搜索,分词匹配多段落重排展示,知识库搜索原理分享

一、背景 在文档搜索场景中&#xff0c;高效精准的搜索功能至关重要&#xff0c;能提升检索效率&#xff0c;为用户提供精准、快速的信息获取体验&#xff0c;提高工作效率。在文档管理系统里&#xff0c;全文搜索是非常重要的功能之一。随着文档数量增长&#xff0c;如何快速…

力扣hot100——回溯

文章目录 前言55.全排列题目描述思路&#xff1a;DFS回溯code 56.子集题目描述思路&#xff1a;dfs回溯code 57.电话号码的字母组合题目描述思路&#xff1a;DFS回溯code 58.数组总和题目描述题目描述code 59.括号生成题目描述思路&#xff1a;DFS回溯code 60.单词搜索题目描述…

云和恩墨亮相PolarDB开发者大会,与阿里云深化数据库服务合作

2025年2月26日&#xff0c;备受瞩目的阿里云PolarDB开发者大会于北京嘉瑞文化中心盛大举行&#xff0c;众多行业精英齐聚一堂&#xff0c;共襄技术盛会。云和恩墨作为阿里云重要的生态合作伙伴受邀参会。云和恩墨联合创始人兼技术研究院总经理杨廷琨与阿里云智能数据库产品事业…

Vue前端项目构建教程

文章目录 1. 引言2.环境准备2.1 请自行查找资料安装以下开发工具2.2 安装cnpm 3. 创建Vue3项目3.1 安装依赖3.2 项目结构 4. 配置Vue项目4.1 在项目根目录下添加环境变量文件4.2 添加环境变量 5. 常用插件和工具总结 1. 引言 本前端项目将使用Vue3 Vite4构建。 Vue3是目前最…

seacms v9 实现的MySQL注入

目录 过滤关键词information_schema 怎么办 一、环境搭建 二、环境分析 三、源代码分析 1、过滤程序 2、注入点 四、获取数据库名 五、获取数据库表名 六、获取表的列名 七、获取数据信息 过滤关键词information_schema 怎么办 1.、利用sys数据库&#xff08;MySQL 5.…