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

《Vuejs 设计与实现》第 4 章(响应式系统)( 上 )

目录

4.1 响应式数据和副作用函数

4.2 基本响应式数据实现

4.3 设计完善响应系统

4.4 分支切换与清理

4.5 嵌套的 effect 与 effect 栈


4.1 响应式数据和副作用函数

副作用函数是指那些产生副作用的函数

function effect() {document.body.innerText = 'hello vue3'
}

执行 effect 函数时,它会设置 body 的文本内容,这种更改可以被其他任何函数读取或设置。
因此,effect 的执行会直接或间接影响其他函数的执行,这就是它产生副作用的地方。
副作用很容易产生,比如修改一个全局变量:

// 全局变量
let val = 1function effect() {val = 2 // 更改全局变量,产生副作用
}

理解了副作用函数后,我们再来看看响应式数据是什么。设想在一个副作用函数中读取了某个对象的属性:

const obj = { text: 'hello world' }function effect() {// 在执行effect函数时会读取 obj.textdocument.body.innerText = obj.text
}

上述代码,effect 函数会设置 body 元素的 innerText 属性,其值为 obj.text。当 obj.text 值发生变化时,我们希望 effect 函数会重新执行:

obj.text = 'hello vue3' // 修改 obj.text 的值,并希望副作用函数重新执行

当 obj.text 值改变时,我们希望副作用函数能自动重新执行。如果这可以实现,那么对象 obj 就可以被称为响应式数据。
但显然,现在我们无法实现这一点,因为 obj 仅仅是一个普通对象,当我们改变它的值时,除了值本身之外,不会有任何其他反应。
下一节我们将讨论如何让数据变为响应式数据。

4.2 基本响应式数据实现

为了使 obj 成为响应式数据,我们可以从以下两点出发:

  1. 执行副作用函数 effect 时,会触发 obj.text 的读取操作。
  2. 当修改 obj.text 的值时,会触发 obj.text 的设置操作。

如果我们能拦截对象的读取和设置操作,这个问题就简单了。

  • 读取 obj.text 时,将副作用函数 effect 存储到一个“桶”中。
  • 在设置 obj.text 时,从“桶”中取出副作用函数 effect 并执行。

在 ES2015 之前,我们可以使用 Object.defineProperty 函数,这是 Vue.js 2 的实现方式。
在 ES2015+ 中,我们可以使用代理对象 Proxy,这是 Vue3 的实现方式。

image.png


 

image.png

 基于以上思路,我们可以用 Proxy 来实现响应式数据:

// 存储副作用函数的桶
const bucket = new Set()// 原始数据
const data = { text: 'hello world' }
// 代理原始数据
const obj = new Proxy(data, {// 拦截读取操作get(target, key) {// 添加副作用函数 effect 到桶中bucket.add(effect)// 返回属性值return target[key]},// 拦截设置操作set(target, key, newVal) {// 设置属性值target[key] = newVal// 取出并执行桶中的副作用函数bucket.forEach(fn => fn())// 返回 true 表示设置成功return true}
})

首先,我们创建一个用于存储副作用函数的 Set 类型的桶 bucket。
然后,定义原始数据 data,并创建其代理对象 obj,我们为代理对象设置了 get 和 set 拦截器,以拦截读取和设置操作。
读取属性时,我们把副作用函数 effect 添加到桶中。
设置属性时,我们先更新原始数据,然后重新执行桶中的副作用函数。这样就实现了响应式数据。
测试一下:

// 副作用函数
function effect() {document.body.innerText = obj.text
}// 触发读取
effect()// 1秒后修改响应式数据
setTimeout(() => {obj.text = 'hello vue3'
}, 1000)

在浏览器中运行以上代码,我们将得到预期的结果。
但当前的实现仍有不足,比如我们是直接通过函数名 effect 获取副作用函数,这种硬编码方式缺乏灵活性。
副作用函数的名字是可以任意命名的,我们可以把副作用函数命名为 myEffect,或者甚至用一个匿名函数。
因此,我们需要找到去除这种硬编码的方法。
下一节将详细讨论这个问题,这里只需理解响应式数据的初步实现和工作原理即可。

4.3 设计完善响应系统

接下来我们将构建一个更完善的响应系统,实现步骤如下:

  1. 读取操作时,将副作用函数收集到“桶”中。
  2. 设置操作时,从“桶”中取出并执行副作用函数。

为了解决硬编码副作用函数名(effect)的问题,我们提供一个注册副作用函数的机制:

// 用一个全局变量存储被注册的副作用函数
let activeEffect// effect 函数用于注册副作用函数
function effect(fn) {// 当调用 effect 注册副作用函数时,将副作用函数 fn 赋值给 activeEffectactiveEffect = fn// 执行副作用函数fn()
}

首先,我们定义了一个全局变量 activeEffect,用于存储被注册的副作用函数。

相关文章:

《Vuejs 设计与实现》第 4 章(响应式系统)( 上 )

目录 4.1 响应式数据和副作用函数 4.2 基本响应式数据实现 4.3 设计完善响应系统 4.4 分支切换与清理 4.5 嵌套的 effect 与 effect 栈 4.1 响应式数据和副作用函数 副作用函数是指那些产生副作用的函数 function effect() {document.body.innerText = hello vue3 }执行 …...

《社交应用架构生存战:React Native与Flutter的部署容灾决胜法则》

React Native和Flutter作为当下热门的跨平台开发框架,在社交应用开发领域各显神通。今天,我们深入探索它们在高可用架构中的部署与容灾策略。 React Native凭借其独特优势,在社交应用开发中拥有一席之地。它基于JavaScript和React&#xff0…...

K8s网络从0到1

K8s网络从0到1 前言 K8s是一个强大的平台,但它的网络比较复杂,涉及很多概念,例如Pod网络,Service网络,Cluster IPs,NodePort,LoadBalancer和Ingress等等。为了帮助大家理解,模仿TC…...

React Native基础环境配置

React Native基础环境配置 1.引言2.React-Native简介3.项目基础环境搭建1.引言 感觉自己掌握的知识面还是有点太窄了,于是决定看看移动端的框架,搞个react搭一个后端管理项目,然后拿react-native写个小的软件,试着找个三方上架一下应用市场玩玩。毕竟不可能一直在简历上挂一…...

k8s术语之DaemonSet

DaemonSet确保全部(或者一些)Node上运行一个Pod的副本。当有Node加入集群时,也会为它们新增一个Pod。当有Node从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除它创建的所有Pod 使用DaemonSet的一些典型用法: …...

接口自动化测试框架详解(pytest+allure+aiohttp+ 用例自动生成)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。 接口测试是比较讲究效…...

Go:简洁高效,构建现代应用的利器

Go,又称 Golang,是由 Google 开发的一种开源编程语言。它以其简洁的语法、高效的性能以及强大的并发特性,在云计算、微服务、DevOps 等领域迅速崛起,成为构建现代应用的利器。本文将带你了解 Go 的魅力,探讨其核心特性…...

Minor GC与Full GC分别在什么时候发生?

一、Minor GC 触发条件 1.Eden区空间不足 • 核心机制&#xff1a;新对象优先分配在Eden区&#xff0c;当Eden区无法满足新对象分配时触发Minor GC。 示例&#xff1a; // 循环创建对象填满Eden区 for (int i 0; i < 1000000; i) {byte[] data new byte[1 * 1024]; // 持…...

Crawl4AI:高效的开源 Python 网页爬取与数据提取库

Crawl4AI:高效的开源 Python 网页爬取与数据提取库 在数据驱动的时代,网页爬取和数据提取是众多 AI 项目及语言模型性能提升的关键环节。Crawl4AI 作为一款开源的 Python 库,凭借强大且灵活的功能,致力于简化这一复杂工作流程。其全异步设计不仅大幅提升了处理速度,还增强…...

【目标检测标签转换工具】YOLO 格式与 Pascal VOC XML 格式的互转详解(含完整代码)

一、写在前面&#xff1a;为什么需要标签格式转换&#xff1f; 在目标检测任务中&#xff0c;不同的模型和标注工具使用的标签格式常常不同&#xff1a; YOLO 系列&#xff08;YOLOv5/v8&#xff09; 使用的是 .txt 格式&#xff0c;每行为一个目标&#xff0c;记录相对归一化…...

Redis最新入门教程

文章目录 Redis最新入门教程1.安装Redis2.连接Redis3.Redis环境变量配置4.入门Redis4.1 Redis的数据结构4.2 Redis的Key4.3 Redis-String4.4 Redis-Hash4.5 Redis-List4.6 Redis-Set4.7 Redis-Zset 5.在Java中使用Redis6.缓存雪崩、击穿、穿透6.1 缓存雪崩6.2 缓冲击穿6.3 缓冲…...

2025年渗透测试面试题总结-某步在线面试(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、操作系统相关问题总结与分析及扩展回答 1. Linux命令熟悉度 2. 查看进程的命令 3. 查看网络进程…...

网络化:DevOps 工程的必要基础(Networking: The Essential Foundation for DevOps Engineering)

李升伟 编译 理解网络化基础知识 你是否曾想过是什么真正让卓越的DevOps工程师与众人区别开来&#xff1f;答案是网络化。是的&#xff0c;对网络的基本理解不仅仅是有帮助的——它是绝对必要的。在当今以微服务、容器和分布式系统为主宰的互联互通世界中&#xff0c;对网络原…...

<template>标签的用法

一、原生的template标签的用法 <template> 是 HTML5 引入的一个标签&#xff0c;用于声明 HTML 片段&#xff0c;这些片段在页面加载时不会被渲染&#xff0c;但可以在运行时通过 JavaScript 实例化和使用。 基本用法 <template id"myTemplate"> <…...

【数据结构】——链表OJ(下)

前面我们已经刷了几道单链表的题目&#xff0c;下面我们继续看几道题目。 一、相交链表 这道题题目的要求是很好理解的&#xff0c;就是现在我们有两个链表&#xff0c;然后我们就相办法进行判断&#xff0c;这两个链表是否是相交的&#xff0c;那么链表的相交其实就是有没有共…...

笔试专题(十六)

文章目录 相差不超过k的最多数题解代码 最长公共子序列&#xff08;一&#xff09;题解代码 小红的口罩题解代码 春游题解代码 相差不超过k的最多数 题目链接 题解 1. 排序 滑动窗口 2. 为什么使用滑动窗口&#xff1f; 因为max-min < k&#xff0c;求这个区间内的数最…...

云原生应用全生命周期管理实战:从开发、部署到运维的一体化方案

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、前言:应用交付正在被“云原生”重塑 随着企业IT架构从单体转向微服务,再到全面拥抱容器化与Kubernetes,应用的构建、部署、配置、监控、弹性与治理也正经历一场全方位的变革。传统的开发运维…...

图表制作-带背景色的柱状图

首先登录自己的账号&#xff0c;没有账号的可以注册一个。 登录之后&#xff0c;在左侧菜单栏找到图表制作-统计图。 点击新建统计图&#xff0c;点击柱状图-带背景色的柱状图。 初始会有一些演示数据&#xff0c;可以根据自己的需要进行修改。 如果觉得手动修改太麻烦&#xf…...

【Pandas】pandas DataFrame ewm

Pandas2.2 DataFrame Function application, GroupBy & window 方法描述DataFrame.apply(func[, axis, raw, …])用于沿 DataFrame 的轴&#xff08;行或列&#xff09;应用一个函数DataFrame.map(func[, na_action])用于对 DataFrame 的每个元素应用一个函数DataFrame.a…...

V 型球阀:多材质多驱动,精准适配复杂严苛工况-耀圣

V 型球阀&#xff1a;多材质多驱动&#xff0c;精准适配复杂严苛工况 在化工、矿业、环保等工业领域&#xff0c;带颗粒介质、料浆以及高腐蚀性介质的输送与控制一直是行业难题。普通阀门在这些复杂工况下&#xff0c;易出现磨损、腐蚀、控制失灵等问题&#xff0c;而 V 型球阀…...

使用C# ASP.NET创建一个可以由服务端推送信息至客户端的WEB应用(2)

接上文 使用C# ASP.NET创建一个可以由服务端推送信息至客户端的WEB应用&#xff08;1&#xff09; https://blog.csdn.net/coldwind811201/article/details/147607641 1. 更新NuGet包 升级NuGet包后&#xff0c;注意相应修改前面页面上的JS引用为相应新版本的jquery JS脚本 …...

Java响应实体【R】

R响应实体 响应实体R(Response Entity)具体作用说明&#xff1f;1、用与数据传输2、用于状态反馈3、指令与控制 普通响应实体优化后的R&#xff1a;高级响应实体类 响应实体R(Response Entity)具体作用说明&#xff1f; 1、用与数据传输 传输请求结果 &#xff1a;当客户端向…...

短视频矩阵系统批量剪辑模式开发详解,支持OEM

在短视频行业竞争激烈的当下&#xff0c;短视频矩阵系统通过批量剪辑功能实现高效内容生产&#xff0c;成为众多运营者的利器。本文将深入探讨短视频矩阵系统中几种常见批量剪辑模式的开发思路与实现方法&#xff0c;助力开发者构建功能强大的批量剪辑模块。 一、批量剪辑模式概…...

顺丰科技:从 Presto 到 Doris 湖仓构架升级,提速 3 倍,降本 48%

导读&#xff1a;顺丰科技引入 Doris 替换 Presto&#xff0c;在内部可视化数据自助分析工具丰景台场景广泛应用。目前&#xff0c;顺丰临时查询业务、丰景台报表业务的 Presto 场景已经 100% 切换到 Doris 集群中&#xff0c;日均查询量 100W。并实现 P95 性能提升近 3 倍&…...

使用 Cesium 构建 3D 地图应用的实践

CesiumJS 是一个功能强大的开源 JavaScript 库&#xff0c;能够帮助开发者快速构建高性能、高精度的 3D 地球和地图应用 。本文将介绍如何使用 Cesium 构建一个基本的 3D 地图应用&#xff0c;并加载自定义的 3D Tiles 模型。 初始化 Cesium Viewer 首先&#xff0c;在 Vue 的…...

公链钱包开发:技术逻辑与产品设计实践

公链钱包开发&#xff1a;技术逻辑与产品设计实践 ——2025年数字资产管理的范式革命与用户价值重构 一、公链钱包的核心理解&#xff1a;技术逻辑与用户价值的耦合 公链钱包不仅是存储数字资产的工具&#xff0c;更是用户与区块链生态交互的“超级入口”。其核心价值体现在三…...

mobile自动化测试-appium webdriverio

WebdriverIO是一款支持mobile app和mobile web自动化测试框架&#xff0c;与appium集成&#xff0c;完成对mobile应用测试。支持ios 和android两种平台&#xff0c;且功能丰富&#xff0c;是mobile app自动化测试首选框架。且官方还提供了mobile 应用测试example代码&#xff0…...

【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现

&#x1f3b5; 【Python开源】深度解析&#xff1a;一款高效音频封面批量删除工具的设计与实现 &#x1f308; 个人主页&#xff1a;创客白泽 - CSDN博客 &#x1f525; 系列专栏&#xff1a;&#x1f40d;《Python开源项目实战》 &#x1f4a1; 热爱不止于代码&#xff0c;热情…...

飞算 用到妙处 AI辅助编程 - 双击方法名,自动识别到上下文中很方便

1. 双击findtasktypedict方法。右侧箭头指向自动识别 2. 按照说的内容机型了修改...

msIT大模型推理迁移调优工具

msIT LLM大模型ATB推理精度工具 适用场景&#xff1a;大模型加速库推理精度分析工具能力&#xff1a;大模型推理精度工具msIT llm&#xff0c;提供基于加速库推理的精度调试工具&#xff0c;支持数据dump、精度比对、单算子预检、溢出检测、模型迁移等能力。 msIT LLM大模型…...

YOGA Air X ILL10(83CX)/YOGA 14 ILL10X(83LC)2025款恢复开箱状态原装出厂Win11系统OEM镜像

适用机型(MTM)&#xff1a; 【83LC】链接&#xff1a;https://pan.baidu.com/s/1AwbFR9nccvyzS1pOCToMvA?pwdewjs 提取码&#xff1a;ewjs 【83CX】链接&#xff1a;https://pan.baidu.com/s/1wMRI8ETodVG59GBDVDLgQg?pwdn3nx 提取码&#xff1a;n3nx lenovo联想原装wi…...

使用Deployment部署运行Nginx和Apache服务

1.Deployment简介 &#xff1a; 在Kubernetes&#xff08;k8s&#xff09;中&#xff0c;Deployment 是一种核心控制器资源&#xff0c;用于管理无状态应用的声明式部署、扩展与更新。它通过定义应用的期望状态&#xff0c;由控制器自动维护实际状态与期望状态的一致性&#x…...

382_C++_在用户会话结束时,检查是否有其他会话仍然来自同一个客户端 IP 地址,没有连接状态设置为断开,否则为连接

之前出现的问题:重启管理机,工作机上面热备连接状态显示未连接 (此时是有一个工作机连接管理机的),所以正常应该是连接状态解决:根因分析: 重启管理机后,管理机给过来的cookie是空的,导致工作机同时存在两个管理机的session,在其中一个超时后,调用回调函数通知会话断开…...

【 Redis | 实战篇 短信登录 】

前言&#xff1a; 主要完成了基于Session实现登录&#xff0c;解决集群的Session共享问题&#xff0c;从而实现了基于Redis来实现共享Session登录 1.基于Session实现登录 1.1.发送短信验证码 步骤&#xff1a; 前端提交手机号 》校验手机号 》不符合返回错误信息&#xff0…...

AI(学习笔记第二课) 使用langchain进行AI开发

文章目录 AI(学习笔记第二课) 使用langchain进行AI开发学习内容&#xff1a;1. 使用背景2.创建python&#xff08;pycharm community版&#xff09;开发环境并连接deepseek2.1 创建python&#xff08;pycharm community版&#xff09;开发环境2.2 创建python工程2.3 写入初始py…...

如何查看某个文件中的特殊符号

Q&#xff1a;如何查看某个文件中的特殊符号&#xff0c;比如说是换行符之类的转义字符&#xff1f; 1&#xff0c;法1&#xff1a;使用cat -A cat -A filename可以看到-A本质上就是-vET&#xff0c;也就是 展示所有的字符&#xff0c;-v是显示非打印字符&#xff0c;这个需…...

venv环境里控制scapy版本和起trex v2.87

要在虚拟环境&#xff08;venv&#xff09;中控制Scapy版本并运行TRex v2.87&#xff0c;您可以按照以下步骤操作&#xff1a; 创建一个新的虚拟环境&#xff1a; python3 -m venv trex-env激活创建的虚拟环境。在Linux或macOS上&#xff1a; source trex-env/bin/activate在Wi…...

第五十四篇 AI与数据分析

一、AI数据分析就像做菜 想象你在厨房做一道新菜&#xff0c;AI数据分析的流程其实非常相似&#xff1a; 买菜&#xff08;获取数据&#xff09; 去市场挑选新鲜蔬菜 从Excel/数据库获取数据例&#xff1a;pd.read_csv(超市销售表.csv) 洗菜切菜&#xff08;清洗数据&#x…...

C++面向对象编程入门:从类与对象说起(一)

C语言是面向过程&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题&#xff0c;而C面向的是对象&#xff0c;关注的是对象&#xff0c;将一件事拆解成多个对象&#xff0c;靠对象之间互交完成。 目录 类的定义 类的两种定义 …...

openwrt之UCI 增删改查(add/get/set /add_list...)

1&#xff0c;引入 UCI是openwrt的统一配置接口&#xff0c;所有的配置文件被存放在/etc/config/下&#xff0c;使用UCI工具操作具体可查询官网中的开发文章&#xff1a; [OpenWrt Wiki] The UCI systemhttps://openwrt.org/docs/guide-user/base-system/uciconifg <secti…...

TypeScript 中,属性修饰符

在 TypeScript 中&#xff0c;属性修饰符&#xff08;Property Modifiers&#xff09;是用于修饰类的属性或方法的关键字&#xff0c;它们可以改变属性或方法的行为和访问权限。TypeScript 提供了三种主要的属性修饰符&#xff1a;public、private 和 protected。此外&#xff…...

LeetCode 3341.到达最后一个房间的最少时间 I:Dijkstra算法(类似深搜)-简短清晰的话描述

【LetMeFly】3341.到达最后一个房间的最少时间 I&#xff1a;Dijkstra算法&#xff08;类似深搜&#xff09;-简短清晰的话描述 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-minimum-time-to-reach-last-room-i/ 有一个地窖&#xff0c;地窖中有 n x m 个房间…...

http重新为https

1.先创建一个配置文件 主要方便实验 可以将主配置文件下的location全部注释掉&#xff0c;方便观察 2.配置新配置文件 server{ listen 80; listen 443 ssl; ssl_certificate /usr/local/nginx/conf.d/ssl/www.kgc.com.crt; ssl_certificate_key /usr/local/nginx/conf…...

2025最新免费视频号下载工具!支持Win/Mac,一键解析原画质+封面

软件介绍 适用于Windows 2025 最新5月蝴蝶视频号下载工具&#xff0c;免费使用&#xff0c;无广告且免费&#xff0c;支持对原视频和封面进行解析下载&#xff0c;亲测可用&#xff0c;现在很多工具都失效了&#xff0c;难得的几款下载视频号工具&#xff0c;大家且用且珍…...

CTF杂项入门(BUUCTF-Misc第一页)

写在前面 题目涵盖&#xff1a;BUUCTF 第一页杂项 涉及工具&#xff1a; 随波逐流、foremost、binwalk、honeyview、010editor、zipperello、archpr、wireshark、cyberchef、QR_Research、PNGCRC爆破、stegsolve、Audacity、河马、D盾、routerpassview、steghide&#xff0c;以…...

碰一碰发视频一键成片功能开发实践与技术解析

在数字化营销与内容传播领域&#xff0c;碰一碰发视频技术凭借便捷的交互体验&#xff0c;已成为实体商业引流的重要手段。而一键成片功能的融入&#xff0c;能够让用户在触碰 NFC 标签后&#xff0c;快速获取高质量的视频内容&#xff0c;进一步提升传播效率。本文将从功能需求…...

【CTFer成长之路】举足轻重的信息搜集

举足轻重的信息搜集 信息搜集 常见的搜集 题目描述: 一共3部分flag docker-compose.yml version: 3.2services:web:image: registry.cn-hangzhou.aliyuncs.com/n1book/web-information-backk:latestports:- 80:80启动方式 docker-compose up -d 题目Flag n1book{info_…...

centos搭建dokcer和vulhub

1、换源阿里云 2、安装docker与docker-compose 下载1.29.2 docker compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 如果下载不了&#xff0c;可以…...

Linux系统下使用Kafka和Zookeeper

Apache Kafka 是一个分布式流处理平台,最初由 LinkedIn 开发,后来成为 Apache 软件基金会的顶级项目。它具有高吞吐量、可扩展性、持久性、容错性等特点,主要用于处理实时数据流。 Linux系统下使用Kafka 1.安装 Java Kafka 和 Zookeeper 都是基于 Java 开发的,所以需要先…...

vscode与keil的乱码不兼容问题

都用英文注释 中文注释的话&#xff0c;打开vscode的自动识别格式,如下 解决VSCode中文乱码 自动识别也可以设置识别优先级&#xff0c;把GB2312和UTF8排在自动识别序列前面(因为keil默认就是GB2312) 4.!!!在暂存更改的时候&#xff0c;不要把vscode的设置给暂存了&#xff…...