vue3.0(五) reactive全家桶
文章目录
- 1 reactive
- 1.1 reactive的应用
- 1.2 reactive的特点
- 1.3 reactive的注意
- 1.4 reactive的局限性
- 2 toRefs
- 3 isReactive
- 4 shallowReactive
- 5 readonly
- 5.1 readonly 详细信息
- 5.2 readonly函数创建一个只读的响应式对象
- 5.3 如何修改嵌套在只读响应式对象中的对象?
- 6 isReadonly
- 7 shallowReadonly
- 8 isProxy
- 总结
1 reactive
1.1 reactive的应用
reactive是另一种声明响应式状态的方式,与将内部值包装在特殊对象中的 ref 不同,reactive() 将使对象本身具有响应性:
import { reactive } from 'vue'
// 声明state
const state = reactive({ count: 0 })
// js中的应用和ref不同不需要valueconsole.log(state)
// html模版中应用<div>{{ state.count }}</div>
响应式对象是 JavaScript 代理,其行为就和普通对象一样。不同的是,Vue 能够拦截对响应式对象所有属性的访问和修改,以便进行依赖追踪和触发更新。
reactive() 将深层地转换对象:当访问嵌套对象时,它们也会被 reactive() 包装。当 ref 的值是一个对象时,ref() 也会在内部调用它。与浅层 ref 类似,这里也有一个 shallowReactive() API 可以选择退出深层响应性。
1.2 reactive的特点
- 实现引用类型数据的响应式,如数组、对象等
- ref去创建引用类型的响应式,其实内部也是调用了reactive
- reactive创建的响应式对象,调用时不用.value
在Vue3中,reactive函数是用于创建响应式对象的函数。它接收一个普通对象作为参数,返回一个代理对象。这个代理对象可以拦截对象的get和set操作,并在其中实现响应式的逻辑。当我们读取代理对象的属性时,会触发依赖收集;当我们修改代理对象的属性时,会触发相应的依赖更新。在调用reactive函数时,Vue3会使用Proxy对象对传入的对象进行代理,从而实现响应式的特性。
1.3 reactive的注意
- reactive() 返回的是一个原始对象的 Proxy,它和原始对象是不相等的:
const obj = {} const proxy = reactive(obj) // 代理对象和原始对象不是全等的 console.log(proxy === obj) // false - 为保证访问代理的一致性,对同一个原始对象调用 reactive() 会总是返回同样的代理对象,而对一个已存在的代理对象调用 reactive() 会返回其本身:
const obj = {} const proxy = reactive(obj) // 在同一个对象上调用 reactive() 会返回相同的代理 console.log(proxy === reactive(obj)) // true // 在一个代理上调用 reactive() 会返回它自己 console.log(reactive(proxy) === proxy) // true
1.4 reactive的局限性
- 有限的值类型:它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。
- 不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:
<template><div>{{ state.count }}</div><button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
export default defineComponent({setup () {let state = reactive({ count: 1 })console.log(state)function mutateDeeply () {// 对state进行替换响应式对象// 上面的 ({ count: 0 }) 引用将不再被追踪// (响应性连接已丢失!)state = reactive({ count: 2 })console.log(state, state.count)}return {mutateDeeply,state}}
})
</script>

- 对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:
<template><div>{{ state.count }}</div><button @click="mutateDeeply">修改数据</button> </template> <script lang="ts"> import { defineComponent, ref, reactive } from 'vue' export default defineComponent({setup () {const state = reactive({ count: 1 })console.log(state)function mutateDeeply () {// 当解构时,count 已经与 state.count 断开连接let { count } = state// 不会影响原始的 statecount++console.log(state, state.count, count)}return {container,mutateDeeply,state}} }) </script> <style scoped> </style>

2 toRefs
- 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
const state = reactive({foo: 1,bar: 2})const stateAsRefs = toRefs(state)/*stateAsRefs 的类型:{foo: Ref<number>,bar: Ref<number>}*/// 这个 ref 和源属性已经“链接上了”console.log(stateAsRefs) // {foo: ObjectRefImpl, bar: ObjectRefImpl}state.foo++console.log(stateAsRefs.foo.value)// 2stateAsRefs.foo.value++console.log(state.foo)// 3- 组件可以解构/展开返回的对象而不会失去响应性:
<template><div>{{ state.foo }}</div><div>{{ state.bar }}</div><button @click="mutateDeeply">修改数据</button> </template> <script lang="ts"> import { defineComponent, reactive, toRefs } from 'vue' export default defineComponent({setup () {const state = reactive({foo: 1,bar: 2})function useFeatureX () {return toRefs(state)}function mutateDeeply () {const { foo, bar } = useFeatureX()foo.value++bar.value++console.log(foo.value, bar.value)}return {mutateDeeply,state}} }) </script> <style scoped> </style>

toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref,请改用 toRef。
3 isReactive
检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。
const state = readonly(reactive({count: 1,name: 'Tom'
}))console.log(state.count)// 1
console.log(state.name)// Tom
console.log(isReactive(state)) // true
4 shallowReactive
- reactive() 的浅层作用形式。
- 和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了
<template><div>{{ state.foo }}</div><div>{{ state.nested.bar }}</div><button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, shallowReactive, isReactive } from 'vue'
export default defineComponent({setup () {const state = shallowReactive({foo: 1,nested: {bar: 2}})// ...但下层嵌套对象不会被转为响应式console.log(isReactive(state.nested)) // falsefunction mutateDeeply () {state.foo++// 不是响应式的 数据state.nested.bar++console.log(state.foo, state.nested, state.nested.bar)}return {mutateDeeply,state}}
})
</script>
5 readonly
接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。
5.1 readonly 详细信息
- 只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。
- 要避免深层级的转换行为,请使用 shallowReadonly() 作替代。
5.2 readonly函数创建一个只读的响应式对象
const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1console.log(state.name)// Tom
5.3 如何修改嵌套在只读响应式对象中的对象?
使用readOnly函数创建的只读对象,内部的属性无法修改
const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1state.name = 'diXi' // 输出警告信息,不会触发依赖更新console.log(state.name)// Tom

注意:使用 readonly 函数创建的只读响应式对象是深层只读的。也就是说,当我们尝试修改嵌套在只读响应式对象中的对象时,会输出警告信息,不会触发相应的依赖更新。
6 isReadonly
- 检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。
- 通过 readonly() 和 shallowReadonly() 创建的代理都是只读的,因为他们是没有 set 函数的 computed() ref。
const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1console.log(state.name)// Tomconsole.log(isReadonly(state)) // true
7 shallowReadonly
- readonly() 的浅层作用形式
- 和 readonly() 不同,这里没有深层级的转换:只有根层级的属性变为了只读。属性的值都会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。
const state1 = readonly(reactive({foo: 1,nested: {bar: 2}}))const state = shallowReadonly(reactive({foo: 1,nested: {bar: 2}}))console.log(state.nested.bar++)// console.log(state1.nested.bar++) // 报错 Cannot assign to 'bar' because it is a read-only property// console.log(state.foo++) // 报错 Cannot assign to 'bar' because it is a read-only property// console.log(state1.foo++) // 报错 Cannot assign to 'bar' because it is a read-only property// ...但可以更改下层嵌套对象isReadonly(state.nested) // false
8 isProxy
检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。
const state = readonly(reactive({count: 1,name: 'Tom'}))console.log(state.count)// 1console.log(state.name)// Tomconsole.log(isProxy(state)) // true
总结
Vue3中用于创建响应式对象的三个函数:
reactive、readonly和shallowReactive。
reactive函数用于创建深层响应式对象,
shallowReactive函数用于创建浅层响应式对象,
readonly函数用于创建深层只读响应式对象,
shallowReadonly函数用于创建浅层只读响应式对象。
这些函数可以帮助我们快速创建响应式数据,实现数据的自动更新。
isProxy,isReadonly,isReactive判断是否是相应是对象
isProxy 检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。
isReadonly 检查传入的值是否为 readonly() 和 shallowReadonly() 创建的只读对象。
isReactive 检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。
相关文章:
vue3.0(五) reactive全家桶
文章目录 1 reactive1.1 reactive的应用1.2 reactive的特点1.3 reactive的注意1.4 reactive的局限性 2 toRefs3 isReactive4 shallowReactive5 readonly5.1 readonly 详细信息5.2 readonly函数创建一个只读的响应式对象5.3 如何修改嵌套在只读响应式对象中的对象? 6 isReadonl…...
Selenium 自动化 —— 四种等待(wait)机制
更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏:专栏《Selenium 从入门到精通》 目录 目录 需要等待的场景 自己实现等待逻辑 Selenium 提供的三种等待机制 隐式等待(Implicit Waits) 隐式等待的优点 隐式等待的缺点 …...
每日两题 / 437. 路径总和 III 105. 从前序与中序遍历序列构造二叉树(LeetCode热题100)
437. 路径总和 III - 力扣(LeetCode) 前序遍历时,维护当前路径(根节点开始)的路径和,同时记录路径上每个节点的路径和 假设当前路径和为cur,那么ans 路径和(cur - target)的出现次数 /*** D…...
matlab使用2-基础绘图
matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点,从0到10,间隔为0.01 y sin(x); % y轴的数据点,是x的正弦…...
嵌入式开发四大平台介绍
MCU(Micro Control Unit)四大平台介绍) 单片机优点:缺点:总结: DSP digital signal processingARM优点:缺点:总结 FPGA什么事FPGA(集成元件库)FPGA开发方法—…...
《Python编程从入门到实践》day28
# 昨日知识点回顾 安装Matplotlib 绘制简单的折线图 # 今日知识点学习 15.2.1 修改标签文字和线条粗细 # module backend_interagg has no attribute FigureCanvas. Did you mean: FigureCanvasAgg? # 解决办法:matplotlib切换图形界面显示终端TkAgg。 #…...
STC8增强型单片机开发【定时器Timer⭐】
目录 一、引言 二、定时器基础知识 三、STC8定时器配置 四、代码示例 五、总结 一、引言 在单片机开发中,定时器(Timer)是一个极其重要的组件,它允许开发者基于时间触发各种事件或任务。STC8增强型单片机作为一款功能丰富的…...
C语言实训项目源码-02餐厅饭卡管理系统-C语言实训C语言大作业小项目
C语言餐厅饭卡管理系统 一、主要功能 主要功能模块 页面名称 实现功能 负责人 进入页面 进入程序 主函数 系统主要功能 修改密码函数 修改密码 充值,显示函数 饭卡充值与信息显示 购买饭菜…...
Linux第四节--常见的指令介绍集合(持续更新中)
点赞关注不迷路!本节涉及初识Linux第四节,主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 ✨ 加关注👀 期待与你共同进步! 1. more指令 语法:more [选项][文件]…...
Apache Sqoop:高效数据传输工具搭建与使用教程
目录 引言一、环境准备二、安装sqoop下载sqoop包解压文件 三、配置Sqoop下载mysql驱动拷贝hive的归档文件配置环境变量修改sqoop-env.sh配置文件替换版本的commons-lang的jar包 验证Sqoop安装查看Sqoop版本测试Sqoop连接MySQL数据库是否成功查看数据库查看数据表去除警告信息 四…...
【C++初阶】第十一站:list的介绍及使用
目录 list的介绍及使用 1.list的含义 2.list的介绍 3.list的使用 1.list的构造 2.list iterator的使用 3.list capacity 4.list element access 5 list modifiers 尾插尾删 和 头插头删 insert 和 erase resize swap clear 6.list sort and reverse 7.list copy vector copy li…...
【devops】Linux 日常磁盘清理 ubuntu 清理大文件 docker 镜像清理
日常磁盘清理 1、查找大文件 find / -type f -size 1G2、清理docker无用镜像(drone产生的残余镜像文件) docker system prune -a一、清理服务器磁盘 1、查找大文件 在Ubuntu系统中,你可以使用find命令来查找大文件。find命令是一个强大的…...
2024年资阳市企业技术中心申报条件、流程要求及支持政策须知
第一章 总则 第一条 为深入贯彻中央、省、市大力实施创新驱动发展战略的部署要求,进一步强化企业技术创新主体地位,引导和支持企业增强技术创新能力,健全技术创新市场导向机制,规范我市企业技术中心(下称“市企业技术…...
社交媒体数据恢复:如流
如流,原名百度Hi,是百度公司开发的一款即时通讯软体。百度Hi具备文字消息、视讯、通话、文件传输等功能。 查找备份:如果您之前有备份如流中的数据,您可以尝试从备份中恢复。如流支持备份至云端,如百度网盘等。 联系客…...
【微信小程序开发(从零到一)【婚礼邀请函】制作】——任务分析和效果实现的前期准备(1)
👨💻个人主页:开发者-曼亿点 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 曼亿点 原创 👨💻 收录于专栏:…...
独孤思维:模仿别人赚钱太难,很痛苦
01 独孤早年混群的时候,想着成为群红,引流。 结果不得其法,别人要什么项目,我就把满是钩子的副业资料发群里。 被群主踢了出去。 我当时还不理解。 后来自己做了社群以后,才明白,这种行为,…...
图片转base64【Vue + 纯Html】
1.template <el-form-item label"图片"><div class"image-upload-container"><input type"file" id"imageUpload" class"image-upload" change"convertToBase64" /><label for"imageU…...
【从零开始学习Redis | 第十一篇】快速介绍Redis持久化策略
前言: Redis 作为一种快速、高效的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景。然而,由于其特性是基于内存的,一旦服务器进程退出,内存中的数据就会丢失。为了解决这一问题,Redis 提供了持久…...
在Ubuntu中如何解压zip压缩包??
2024年5月15日,周三上午 使用 unzip 命令 unzip 文件名.zip这会将压缩包中的内容解压到当前目录。如果想解压到特定目录,可以使用 -d 选项,例如: unzip 文件名.zip -d 目标目录使用 7-zip 还可以安装 7-zip 工具来解压 ZIP 文件。…...
LeetCode 126题:单词接龙 II
❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
