《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&#…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
SQL注入篇-sqlmap的配置和使用
在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap,但是由于很多朋友看不了解命令行格式,所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习,链接:https://wwhc.lanzoue.com/ifJY32ybh6vc…...
AWSLambda之设置时区
目标 希望Lambda运行的时区是东八区。 解决 只需要设置lambda的环境变量TZ为东八区时区即可,即Asia/Shanghai。 参考 使用 Lambda 环境变量...
设计模式域——软件设计模式全集
摘要 软件设计模式是软件工程领域中经过验证的、可复用的解决方案,旨在解决常见的软件设计问题。它们是软件开发经验的总结,能够帮助开发人员在设计阶段快速找到合适的解决方案,提高代码的可维护性、可扩展性和可复用性。设计模式主要分为三…...
