探究Vue3中的Composition API:优化组件逻辑的新利器
一、toRef函数
在 Vue 3.0 中,引入了一种新的响应式 API,即
toRef。toRef函数可以将一个普通值转换为响应式引用类型,这样就可以在模板中直接使用这个响应式引用类型的属性,并且当该属性发生变化时,视图会自动更新。
<template><div><h2>年龄:{{ age }}</h2><h2>原值:{{person.age }}</h2><button @click="age++;console.log(age)">年龄增加</button></div>
</template><script>
import { reactive} from 'vue';export default {name: 'TodoList',setup() {// 使用 ref 创建响应式数据const person = reactive({name: 'JingYu',age: 18,})// 暴露数据和方法给模板使用return {age:person.age,person,};},
};
</script>
通过控制台打印输出的内容和页面的变化,我们可以观察到,age的值一直在变化,但其不是响应式的,所以页面没有随着值的变化而更新视图。这是因为这种写法就好比我们定义了一个新的变量,将person.age的值18赋值给这个变量。但这个变量并不是响应式的。

这时我们就可以通过toRef将其转换为响应式的
const person = reactive({name: 'JingYu',age: 18,})// 暴露数据和方法给模板使用let age=toRef(person,'age')console.log(age)return {age,person,};
细心地同学可能从上面的代码中注意到了一点,我在页面中还显示了一个person.age的值。
<div><h2>年龄:{{ age }}</h2><h2>原值:{{person.age }}</h2><button @click="age++;console.log(age)">年龄增加</button></div>
为什么要展示它的值呢,看了将person中age属性单独转换成一个单独的响应式引用之后,你就会发现,页面展示的两个值都会随之改变。

如果你不小心写成了这种形式
let age=toRef(person.age)
你就会惊奇的发现,页面展示的person.age不会随之改变了.

这里需要注意一下两种写法的区别:
1.当你使用
toRef(person, 'age')时,你是在告诉Vue你希望将person对象的age属性转换为一个单独的响应式引用。这意味着当person.age的值发生变化时,引用的值也会相应地更新。
2.toRef(person.age)是将person.age直接转换为响应式引用,而不是从person对象中获取对age属性的引用。这意味着当你修改person.age的值时,引用的值不会自动更新。
二、toRefs函数
torefs和toRef的作用是一样的,只不过toRefs是将一个对象的所有属性都变为单独的响应式。
setup() {// 使用 ref 创建响应式数据const person = reactive({name: 'JingYu',age: 18,})// 暴露数据和方法给模板使用return {...toRefs(person)};},
通过使用扩展运算符将person对象的所有属性展开返回。成功实现单个属性的响应式。

三、shallowReactive 与 shallowRef
shallow是浅的、浅显的意思。
顾名思义:
shallowReactive:只处理对象最外层属性的响应式(浅响应式)
<h2>年龄{{ person.age }}</h2><h2>薪资{{ person.job.salary }}</h2><button @click="person.age++;console.log(person.age,'---')">年龄增加</button><button @click="person.job.salary++;console.log(person.job.salary)">薪资增加</button>const person = shallowReactive({name: 'JingYu',age: 18,job:{name:'前端开发',salary:8}})
我们可以观察到年龄是响应式的,而第二层的属性薪资就不是响应式的了。

shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。
<h2>年龄{{ person.age }}</h2><button @click="person.age++;console.log(person.age,'---')">年龄增加</button>const person = shallowRef({name: 'JingYu',age: 18,})
虽然person.age的值改变了,但数据并不是响应式的,所以页面视图没有更新。

- 使用场景
1.如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive。
2.如果有一个对象数据,后续功能不会修改该对象中的属性,而是用新的对象来替换 ===> shallowRef。
解释一下这句话:
<h2>年龄{{ person.age }}</h2><button @click="person={age:20}">年龄改变</button>
此时点击按钮页面会变为20,因为我们改变的不是x里面的属性,而是将整个person对象重新赋值,person是响应式。的。
四、readonly 与 shallowReadonly
readonly: 让一个响应式数据变为只读的(深只读)。
如果使用readonly修饰对象person,所有的属性都不能修改了。当你修改时控制台还会输出警告.
<template><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>薪资:{{job.j1.salary}}K</h2><button @click="name+='~'">修改姓名</button><button @click="age++">增长年龄</button><button @click="job.j1.salary++">涨薪</button>
</template><script>import {reactive,toRefs,readonly} from 'vue'export default {name: 'HelloWorld',setup(){//数据let person = reactive({name:'张三',age:18,job:{j1:{salary:20}}})person = readonly(person)//返回一个对象(常用)return {...toRefs(person)}}}
</script>

如果使用shallowReadonly修饰对象person,只有最外层的不能修改了。salary还是可以修改的。
<template><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>薪资:{{job.j1.salary}}K</h2><button @click="name+='~'">修改姓名</button><button @click="age++">增长年龄</button><button @click="job.j1.salary++">涨薪</button>
</template><script>import {reactive,toRefs,shallowReadonly} from 'vue'export default {name: 'HelloWorld',setup(){//数据let person = reactive({name:'张三',age:18,job:{j1:{salary:20}}})person = shallowReadonly(person)//返回一个对象(常用)return {...toRefs(person)}}}
</script>

五、toRaw 与 markRaw
toRaw是一个用于将响应式对象转换为其原始非响应式版本的函数。
toRaw函数接受一个响应式对象作为参数,并返回该对象的原始非响应式版本。它实际上返回了一个指向原始对象的引用,而不是创建一个新的对象。
import { reactive, toRaw } from 'vue'
const originalObj = { foo: 'bar' }
const reactiveObj = reactive(originalObj)
console.log(reactiveObj.foo) // 输出 "bar"
const rawObj = toRaw(reactiveObj)
rawObj.foo = 'baz' // 修改原始对象
console.log(reactiveObj.foo) // 输出 "baz"
markRaw是Vue3中用于标记一个对象,使其永远不会转换为响应式对象的函数。
有些值不应被设置为响应式的,例如复杂的第三方类库或Vue组件对象。在这种情况下,我们可以使用markRaw函数。
import { reactive, markRaw } from 'vue'
const originalObj = { foo: 'bar' }
const reactiveObj = reactive(originalObj)
console.log(reactiveObj.foo) // 输出 "bar"
const rawObj = markRaw(originalObj)
console.log(isReactive(reactiveObj)) // 输出 "true"
console.log(isReactive(rawObj)) // 输出 "false"
// 尝试将rawObj转换为响应式对象
const reactiveRawObj = reactive(rawObj)
console.log(isReactive(reactiveRawObj)) // 输出 "false"
在上面的示例中,我们首先使用reactive函数将originalObj转换为一个响应式对象reactiveObj。然后,我们使用markRaw函数将originalObj转换为其非响应式版本rawObj。我们使用isReactive函数验证了reactiveObj是响应式对象,而rawObj不是。最后,我们尝试将rawObj转换为响应式对象,但是通过isReactive函数验证后发现,转换并未生效。
六、provide 与 inject
在Vue 3中,provide和inject是用于跨层级组件通信的两种方法。
provide方法允许父组件向下传递数据给子组件。provide() 接受两个参数:第一个参数是要注入的 key,可以是一个字符串或者一个 symbol,第二个参数是要注入的值。
inject方法允许子组件从父组件中获取传递的数据。它接收两个参数:一个是需要注入的键值,另一个是默认值。如果父组件没有提供该键值,则inject方法将返回默认值。
具体用法
祖组件中:
setup(){......let car = reactive({name:'奔驰',price:'40万'})provide('car',car)......
}
后代组件:
setup(props,context){......const car = inject('car')return {car}......
}
响应式数据的判断
- isRef: 检查一个值是否为一个 ref 对象
- isReactive: 检查一个对象是否是由
reactive创建的响应式代理 - isReadonly: 检查一个对象是否是由
readonly创建的只读代理 - isProxy: 检查一个对象是否是由
reactive或者readonly方法创建的代理
相关文章:
探究Vue3中的Composition API:优化组件逻辑的新利器
一、toRef函数 在 Vue 3.0 中,引入了一种新的响应式 API,即 toRef。toRef 函数可以将一个普通值转换为响应式引用类型,这样就可以在模板中直接使用这个响应式引用类型的属性,并且当该属性发生变化时,视图会自动更新。 <templat…...
Google Services Framework 谷歌服务框架的安装以及遇到的常见问题
安装谷歌三件套: 1、Google 服务框架(Google Services Framework)下载地址: https://www.apkmirror.com/apk/google-inc/google-services-framework/ 注意一定要选择与自己手机对应的安卓系统版本的服务框架。 2、Google Play Se…...
学习高级数据结构:探索平衡树与图的高级算法
文章目录 1. 平衡树:维护数据的平衡与高效性1.1 AVL 树:严格的平衡1.2 红黑树:近似平衡 2. 图的高级算法:建模复杂关系与优化2.1 最小生成树:寻找最优连接方式2.2 拓扑排序:解决依赖关系 拓展思考 …...
centos7离线安装neo4j
一、准备需要的rpm包 本地环境执行如下命令: docker pull couchbase/centos7-systemd docker run -it couchbase/centos7-systemd bash # 可能需要换源 yum update -y vi /etc/yum.conf # 修改其中的keepcache1 rpm --import https://debian.neo4j.com/neotechnol…...
【黑马头条之项目部署_持续集成Jenkins】
本笔记内容为黑马头条项目的项目部署_持续集成部分 目录 一、内容介绍 1、什么是持续集成 2、持续集成的好处 3、今日内容 二、软件开发模式 1、软件开发生命周期 2、软件开发瀑布模型 3、软件的敏捷开发 三、Jenkins安装配置 1、Jenkins介绍 2、Jenkins环境搭建 …...
前端自动化部署,Devops,CI/CD
DevOps 提到 Jenkins,想到的第一个概念就是 CI/CD 在这之前应该再了解一个概念。 DevOps Development 和 Operations 的组合,是一种方法论,并不特指某种技术或者工具。DevOps 是一种重视 Dev 开发人员和 Ops 运维人员之间沟通、协作的流程。…...
22 元类技术(面向切片编程)|ORM的实现|抽象类与接口类
文章目录 前情知识补充hasattr 函数setattr函数getattr函数join 函数 元类技术使用type创建类什么是元类(概念总结)\_\_metaclass\_\_属性使用metaclass 的函数方式进行创建类使用metaclass 的类方式进行创建类 自定义元类 元类实现ORM接口类与抽象类抽象…...
fuchsia系统介绍
fuchsia系统 Fuchsia,是由Google公司开发的继Android和Chrome OS之后的第三个系统,已在Github中公开的部分源码可以得知。Google对于Fuchsia的说明是“Pink(粉红)Purple(紫色)Fuchsia(灯笼海棠…...
解决Jenkins执行Python脚本不能实时输出打印信息的问题
问题: 在使用Jenkins的shell command来执行python脚本时,总是会等脚本执行完毕,最后一次性才把脚本中的print语句给打印出来; 解决方法: 在print语句后加上sys.stdout.flush(), 就可以达到实时输出的目的了。...
2021年03月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:最小新整数 给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。 现在从m位中删除k位(0<k < m),求生成的新整数最小为多少? 例如: n = 9128456, k = 2, 则生成的新整数最小为12456 时间…...
【微服务】服务发现和管理技术框架选型调研
选型背景 方案对比 结论 结合实际业务和开发需要,着重考虑性能可靠性、功能和社区支持程度三方面,认为Nacos更适合作为服务发现和管理的技术框架。具体理由如下: 性能更好,可靠性更高 经过阿里、APISIX、SpringCloudAlibaba,阿…...
【核磁共振成像】观共享重建
目录 一、K空间关键孔技术-数据采集二、BRISK技术三、TRICKS技术四、实时成像和滑动窗重建五、心电触发电影(CINE)采集六、分段心脏采集和观共享 一、K空间关键孔技术-数据采集 对于笛卡尔K空间,一个相位编码行有时称为一个K空间观。一般情况下,每帧图像…...
〔020〕Stable Diffusion 之 骨骼姿势 篇
✨ 目录 🎈 姿势检测 / OpenPose🎈 姿势检测 OpenPose 参数介绍🎈 姿势检测 OpenPose 基本使用🎈 深度库 / Depth Lib🎈 深度库 Depth Lib 参数介绍🎈 3D姿势检测 / 3D Openpose Editor🎈 3D姿势检测 3D Openpose Editor 参数介绍🎈 3D姿势检测 3D Openpose Ed…...
使用Python进行Base64编码和解码
假设您有一个想要通过网络传输的二进制图像文件。您很惊讶对方没有正确接收该文件 - 该文件只是包含奇怪的字符! 嗯,您似乎试图以原始位和字节格式发送文件,而所使用的媒体是为流文本而设计的。 避免此类问题的解决方法是什么?答…...
MongoDB的数据恢复与备份
MongoDB的数据恢复与备份 在MongoDB中,备份和恢复数据是一项关键任务,可以确保数据的安全性并防止意外数据丢失。本文将介绍MongoDB的数据恢复与备份原理并提供相关的编程代码和配置。 1. 数据备份原理 MongoDB提供了多种备份数据…...
Java之SpringCloud Alibaba【五】【微服务 Sentinel整合openfeign进行降级】
一、Sentinel整合openfeign 1、复制一下order-openfeign项目(创建order-openfeign-sentinel) 然后在stock-nacos当中编写对应的接口 RequestMapping("/reduct2")public String reduct2(){int a 1/0;System.out.println("扣减库存"…...
电脑前置耳机没声音怎么办
有很多小伙伴反映在将自己的耳机连接到主机前面时没有声音,这是怎么回事呢,遇到这种情况应该怎么解决呢,下面小编就给大家详细介绍一下电脑前置耳机没声音的解决方法,有需要的小伙伴可以来看一看电脑前面耳机没声音。 解决方法&a…...
package.json 详解
文章目录 package.json1. name2. version3. description4. homepage5. bugs6. license7. author, contributors8. funding9. files10. main11. module12. browser13. bin14. man15. directories15.1 directories.bin15.2 directories.man 16. repository17. scripts18. config1…...
springboot配置ym管理各种日记(log)
1:yml配置mybatis_plus默认日记框架 mybatis-plus:#这个作用是扫描xml文件生效可以和mapper接口文件使用,#如果不加这个,就无法使用xml里面的sql语句#启动类加了MapperScan是扫描指定包下mapper接口生效,如果不用MapperScan可以在每一个mapp…...
你知道Vue 3.0中Treeshaking特性吗?
介绍 Vue 3.0引入了Tree-shaking特性,旨在优化构建过程并减小最终生成的代码大小。Tree-shaking是一种在构建时移除未使用代码的技术,通过分析模块的依赖关系,将没有被引用的部分从最终的打包文件中排除掉。这可以大大减少应用的体积&#x…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
