《Vue进阶教程》第十一课:响应式系统介绍
1 什么是响应式
当数据改变时, 引用数据的函数会自动重新执行
2 手动完成响应过程
首先, 明确一个概念: 响应式是一个过程, 这个过程存在两个参与者: 一方触发, 另一方响应
比如说, 我们家小胖有时候不乖, 我会打他, 他会哭. 这里我就是触发者, 小胖就是响应者
同样, 所谓数据响应式的两个参与者
- 触发者: 数据
- 响应者: 引用数据的函数
当数据改变时, 引用数据的函数响应数据的改变, 重新执行
我们先手动完成响应过程
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"></div><script>// 定义一个全局对象: `触发者`const obj = { name: 'hello' }// effect函数引用了obj.name, 这个函数就是 `响应者`function effect() {// 这里可以通过app拿到DOM对象app.innerHTML = obj.name}effect()// 当obj.name改变时, 手动执行effect函数, 完成响应过程setTimeout(() => {obj.name = 'brojie'effect()}, 1000)</script></body>
</html>
为了方便, 我们把引用了数据的函数 叫做 副作用函数
3 副作用函数
如果一个函数引用了外部的资源, 这个函数会受到外部资源改变的影响
我们就说这个函数存在副作用. 因此, 也把该函数叫做副作用函数
这里, 大家不要被这个陌生的名字吓唬住 所谓副作用函数就是引用了数据的函数或者说数据关联的函数
4 自定义设置过程
如果我们能感知数据改变, 拦截到赋值操作. 自定义设置过程 在赋值的同时调用一下数据关联的副作用函数, 就可以实现自动重新执行 理论上可行, 开始动手实践
1) Proxy代理对象
这里我们需要先补充一下Proxy相关的知识. 如果已经知道的小伙伴可以略过 new Proxy: 传入一个源对象, 返回一个新对象(代理对象) 当访问代理对象的属性时, 可以自定义访问过程 当设置代理对象的属性时, 可以自定义设置过程
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>// 定义一个源对象(目标对象)const obj = { name: 'xiaopang' }// 创建一个代理对象const proxy = new Proxy(obj, {get(target, key) {// 当访问proxy代理对象的属性时, 会执行get函数// 将get函数的返回值作为表达式的值console.log(target, key)return target[key] // obj.name obj[name]},set(target, key, value) {// 当设置proxy代理对象的属性时, 会执行set函数console.log('自定义set操作', value)target[key] = valuereturn true},})// console.log(proxy.name)// console.log(proxy.age)proxy.name = 'xxp'console.log(obj)</script></body>
</html>
这样就确定了思路
- 先创建代理对象
- 再操作代理对象(给代理对象赋值)
2) 最基本的reactive函数
定义一个函数reactive
, 传入一个普通对象, 返回代理对象
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>function isObject(value) {return typeof value === 'object' && value !== null}/*** 创建响应式数据* @param [object]: 普通对象* @return [Proxy]: 代理对象*/function reactive(data) {if (!isObject(data)) returnreturn new Proxy(data, {get(target, key) {return target[key]},set(target, key, value) {target[key] = valuereturn true},})}const state = { name: 'xiaopang' }const p = reactive(state)p.name = 'xxp'console.log(p.name)</script></body>
</html>
5 最基本的响应式
既然可以自定义set操作, 只需要在自定义set操作时, 重新执行属性关联的副作用函数
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app">hello</div><script>/*** 定义响应式* @param [object] : 普通对象* @return [Proxy] : 代理对象*/function reactive(data) {// 如果传入的data不是一个普通对象, 不处理if (typeof data !== 'object' || data == null) returnreturn new Proxy(data, {get(target, key) {console.log(`自定义访问${key}`)return target[key]},set(target, key, value) {console.log(`自定义设置${key}=${value}`)target[key] = value // 先更新值effect() // 再调用effect, 调用effect时会重新获取新的数据return true},})}const pState = reactive({ name: 'hello' })function effect() {app.innerHTML = pState.name}setTimeout(() => {pState.name = 'brojie'}, 1000)</script></body>
</html>
看到这里, 恭喜你, 已经掌握了最核心的原理🤝
💡 小结
- 响应式是一个过程, 存在触发者和响应者
- 数据的改变, 触发关联的副作用函数响应(重新执行)
- 通过Proxy代理源数据
- 在Proxy的自定义set操作中, 重新执行副作用函数
相关文章:
《Vue进阶教程》第十一课:响应式系统介绍
1 什么是响应式 当数据改变时, 引用数据的函数会自动重新执行 2 手动完成响应过程 首先, 明确一个概念: 响应式是一个过程, 这个过程存在两个参与者: 一方触发, 另一方响应 比如说, 我们家小胖有时候不乖, 我会打他, 他会哭. 这里我就是触发者, 小胖就是响应者 同样, 所谓…...
rpc设计的再次思考20251215(以xdb为核心构建游戏框架)
1.服务提供者注册的方式 // 表明这是一个服务提供者,ServerType 和 ServerId从application.properties中读取 // 而且只有当当前服务是Game时,才生效。 或者 条件注解??? RpcProvider(typeServerType.Game) public class GameProvider{MsgReceiver…...

pydub AudioSegment增加音频文件音量并保存- python 实现
DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” -------------------------------------------------------------…...

IT 新突破!远程控制电脑技术造就工作与学习新方向!
远程控制电脑技术的历史可追溯到计算机网络的早期时代。最初,通过电话线和调制解调器的组合,实现了远程访问,这是远程控制电脑技术的雏形。随着互联网技术的飞速发展,远程控制电脑技术也日趋完善,并在多个领域得到了广…...

LabVIEW起落架震台检测
在现代飞机制造与维护过程中,起落架的性能测试是保障飞机安全的重要环节。通过LabVIEW开发的起落架小落震台检测系统,通过模拟飞机着陆过程,准确捕捉起落架在着陆时承受的各种动力学特性和应力响应,有效提升起落架设计的精度与可靠…...
Day24 C++ 接口(抽象类)
C 接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现。 C 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。 如果类中至少有一个函数被声明…...
UE5 关于画质、机能与开发成本的思考
1、并不省时间 UE5等工具优点是可以通过一些工具与资源快速获得较好的画面,节约一些时间, 但缺点也很多, 一个是各种精度的素材之间的协调问题,参差不齐,统一升级到高精度会产生较大的成本, 一个是资源…...

IOS学习路线图
iOS是由苹果公司开发的移动操作系统。 苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad上。iOS与苹果的macOS操作系统一样,属于类Unix的商业操作系统。原本这个系统名为…...

HICE-day6
二层交换 交换基础 所谓的二层交换机指的是针对数据的二层头部(以太网帧头)中的MAC地址进行寻址并转发数据的交换设备。二层交换机不具备路由功能,它工作在OSI七层模型的第二层,因此被称为二层交换机。 上图中,PC1、…...

第100+33步 ChatGPT学习:时间序列EMD-ARIMA-LSTM模型
基于Python 3.9版本演示 一、写在前面 上一节,我们学了经验模态分解(Empirical Mode Decomposition,EMD)。 如同结尾所说,“那么,做这些分解有什么作用呢?有大佬基于这些分解出来的序列分别作…...
(C语言)双向链表
目录 链表的分类 双向链表的实现 1)定义链表 2)初始化双向链表 3)申请节点 4)尾插 5)头插 6)打印链表 7)尾删 8)头插 9)查找 10)指定位置删除 11…...
青少年编程与数学 02-004 Go语言Web编程 04课题、接收和处理请求
青少年编程与数学 02-004 Go语言Web编程 04课题、接收和处理请求 课题摘要:一、构建WEB服务器1. 安装Go语言2. 创建项目结构3. 编写代码4. 运行WEB服务器5. 访问WEB服务器 二、接收请求1. 定义处理函数(Handler)2. 将处理函数与路由关联3. 启动服务器4. …...

Unity全局光照详解
之前就学过但是太久没用又忘了,因此用最简洁易懂的语言做个记录。 全局光照分为两个系统,分别是实时光照和混合光照。(点击window/Rendering/Lighing打开此面板) 其中全局光照对于我来说都是新技术了,上一次学…...

计算机网络知识点全梳理(三.TCP知识点总结)
目录 TCP基本概念 为什么需要TCP 什么是TCP 什么是TCP链接 如何唯一确定一个 TCP 连接 TCP三次握手 握手流程 为什么是三次握手,而不是两次、四次 为什么客户端和服务端的初始序列号 ISN 不同 既然 IP 层会分片,为什么 TCP 层还需要 MSS TCP四…...
ELK Stack 安装、配置以及集成到 Java 微服务中的使用
ELK Stack 是由 Elasticsearch、Logstash 和 Kibana 组成的日志管理解决方案。以下是详细的安装、配置步骤以及如何将其集成到 Java 微服务中。 1. 安装 ELK Stack 1.1 安装 Elasticsearch 在 Ubuntu 上安装 Elasticsearch: bash wget -qO - https://artifacts…...

list_
1.对象创建 // // Created by 徐昌真 on 2024/12/12. // #include <iostream> #include <list>using namespace std;void Print(list<int> &my_list) {for ( list<int>::iterator iter my_list.begin(); iter ! my_list.end(); iter ){cout <…...
电机驱动,为什么不需要变速器?
在现代汽车和工业应用中,电机驱动的技术愈发成熟,其核心优势之一是能够省去传统机械变速器的需求。 一、电机驱动的基本原理 电机驱动又被称为电动机驱动,其基本原理是将电能转化为机械能。通过控制电机的输入电压和电流,电机能…...
how to write 述职pptx as a tech manager
As a technical manager, crafting an effective 述职 (performance review) PPT requires you to highlight your leadership, team accomplishments, technical contributions, challenges faced, and future plans. Heres a structured approach to design your PPT: 1. Cov…...
关于QMessageBox的一些使用总结和避坑指南
参考学习 Qt中QMessageBox的用法—看这一篇就够了 Qt:使用QMessageBox弹出标准对话框 QMessageBox模态与非模态及QT中的exec() 如何调整QMessageBox的大小 QSS 自定义QMessageBox python QMessageBox设置标签和按钮居中、中文按钮 使用建议 经过查看多方的资料&…...

C语言预处理详解
1.预定义符号 C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的 __FILE__ //进⾏编译的源⽂件 __LINE__ //⽂件当前的⾏号 __DATE__ //⽂件被编译的⽇期 __TIME__ //⽂件被编译的时间 __STDC__ //如果编译器遵循ANSI C&#…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...