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…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...