总结Vue3里一些常见的组合式api

一:前言

二:常见api

1、ref 和 reactive

        这两个组合式 api 是在 Vue3 开发中最为常见的两个 api ,主要是将一个非响应式的数据变为响应式数据。

        ref作用: 定义一个数据的响应式

  • 语法: const xxx = ref(initValue):
  • 创建一个包含响应式数据的引用(reference)对象
  • js中操作数据: xxx.value
  • 模板中操作数据: 不需要.value
  • 一般用来定义一个基本类型的响应式数据

        reactive作用: 定义多个数据的响应式

  • 语法:const proxy = reactive(obj):
  • 响应式转换是“深层的”:会影响对象内部所有嵌套的属性
  • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
  • 接收一个普通对象然后返回该普通对象的响应式代理器对象

代码:

// ref
<template><h2>{{count}}</h2><hr><button @click="update">更新</button>
</template><script>
import {ref
} from 'vue'
export default {/* 使用vue3的composition API */setup () {// 定义响应式数据 ref对象const count = ref(1)console.log(count)// 更新响应式数据的函数function update () {// alert('update')count.value = count.value + 1}return {count,update}}
}
</script>// reactive
<template><h2>name: {{state.name}}</h2><h2>age: {{state.age}}</h2><h2>wife: {{state.wife}}</h2><hr><button @click="update">更新</button>
</template><script>
import {reactive,
} from 'vue'
export default {setup () {/* 定义响应式数据对象*/const state = reactive({name: 'tom',age: 25,wife: {name: 'marry',age: 22},})console.log(state, state.wife)const update = () => {state.name += '--'state.age += 1state.wife.name += '++'state.wife.age += 2}return {state,update,}}
}
</script>

2、shallowRef和shallowReactive

  • shallowReactive : 只处理了对象内最外层属性的响应式(也就是浅响应式)

  • shallowRef: 只处理了value的响应式, 不进行对象的reactive处理

  • 什么时候用浅响应式呢?

    • 一般情况下使用ref和reactive即可
    • 如果有一个对象数据, 结构比较深, 但变化时只是外层属性变化 ===> shallowReactive
    • 如果有一个对象数据, 后面会产生新的对象来替换 ===> shallowRef
<template><h2>App</h2><h3>m1: {{m1}}</h3><h3>m2: {{m2}}</h3><h3>m3: {{m3}}</h3><h3>m4: {{m4}}</h3><button @click="update">更新</button>
</template><script lang="ts">
import { reactive, ref, shallowReactive, shallowRef } from 'vue'export default {setup () {const m1 = reactive({a: 1, b: {c: 2}})const m2 = shallowReactive({a: 1, b: {c: 2}})const m3 = ref({a: 1, b: {c: 2}})const m4 = shallowRef({a: 1, b: {c: 2}})const update = () => {m4.value.a += 1}return {m1,m2,m3,m4,update,}}
}
</script>

3、 readonly 与 shallowReadonly

  • readonly:
    • 深度只读数据
    • 获取一个对象 (响应式或纯对象) 或 ref 并返回原始代理的只读代理。
    • 只读代理是深层的:访问的任何嵌套 property 也是只读的。
  • shallowReadonly
    • 浅只读数据
    • 创建一个代理,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换
  • 应用场景:
    • 在某些特定情况下, 我们可能不希望对数据进行更新的操作, 那就可以包装生成一个只读代理对象来读取数据, 而不能修改或删除
<template><h2>App</h2><h3>{{state}}</h3><button @click="update">更新</button>
</template><script lang="ts">
import { reactive, readonly, shallowReadonly } from 'vue'export default {setup () {const state = reactive({a: 1,b: {c: 2}})// const rState1 = readonly(state)const rState2 = shallowReadonly(state)const update = () => {// rState1.a++ // error// rState1.b.c++ // error// rState2.a++ // errorrState2.b.c++}return {state,update}}
}
</script>

4、 toRaw 与 markRaw

  • toRaw
    • 返回由 reactive 或 readonly 方法转换成响应式代理的普通对象。
    • 这是一个还原方法,可用于临时读取,访问不会被代理/跟踪,写入时也不会触发界面更新。
  • markRaw
    • 标记一个对象,使其永远不会转换为代理。返回对象本身
    • 应用场景:
      • 有些值不应被设置为响应式的,例如复杂的第三方类实例或 Vue 组件对象。
      • 当渲染具有不可变数据源的大列表时,跳过代理转换可以提高性能。
<template><h2>{{state}}</h2><button @click="testToRaw">测试toRaw</button><button @click="testMarkRaw">测试markRaw</button>
</template><script lang="ts">
/* 
toRaw: 得到reactive代理对象的目标数据对象
*/
import {markRaw,reactive, toRaw,
} from 'vue'
export default {setup () {const state = reactive<any>({name: 'tom',age: 25,})const testToRaw = () => {const user = toRaw(state)user.age++  // 界面不会更新}const testMarkRaw = () => {const likes = ['a', 'b']// state.likes = likesstate.likes = markRaw(likes) // likes数组就不再是响应式的了setTimeout(() => {state.likes[0] += '--'}, 1000)}return {state,testToRaw,testMarkRaw,}}
}
</script>

5、toRef

  • 为源响应式对象上的某个属性创建一个 ref对象, 二者内部操作的是同一个数据值, 更新时二者是同步的
  • 区别ref: 拷贝了一份新的数据值单独操作, 更新时相互不影响
  • 应用: 当要将 某个prop 的 ref 传递给复合函数时,toRef 很有用
<template><h2>App</h2><p>{{state}}</p><p>{{foo}}</p><p>{{foo2}}</p><button @click="update">更新</button><Child :foo="foo"/>
</template><script lang="ts">
import {reactive,toRef,ref,
} from 'vue'
import Child from './Child.vue'export default {setup () {const state = reactive({foo: 1,bar: 2})const foo = toRef(state, 'foo')const foo2 = ref(state.foo)const update = () => {state.foo++// foo.value++// foo2.value++  // foo和state中的数据不会更新}return {state,foo,foo2,update,}},components: {Child}
}
</script>
<template><h2>Child</h2><h3>{{foo}}</h3><h3>{{length}}</h3>
</template><script lang="ts">
import { computed, defineComponent, Ref, toRef } from 'vue'const component = defineComponent({props: {foo: {type: Number,require: true}},setup (props, context) {const length = useFeatureX(toRef(props, 'foo'))return {length}}
})function useFeatureX(foo: Ref) {const lenth = computed(() => foo.value.length)return lenth
}export default component
</script>

6、customRef

  • 创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制
  • 需求: 使用 customRef 实现 debounce 的示例
<template><h2>App</h2><input v-model="keyword" placeholder="搜索关键字"/><p>{{keyword}}</p>
</template><script lang="ts">
/*
customRef:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制需求: 使用 customRef 实现 debounce 的示例
*/import {ref,customRef
} from 'vue'export default {setup () {const keyword = useDebouncedRef('', 500)console.log(keyword)return {keyword}},
}/* 
实现函数防抖的自定义ref
*/
function useDebouncedRef<T>(value: T, delay = 200) {let timeout: numberreturn customRef((track, trigger) => {return {get() {// 告诉Vue追踪数据track()return value},set(newValue: T) {clearTimeout(timeout)timeout = setTimeout(() => {value = newValue// 告诉Vue去触发界面更新trigger()}, delay)}}})
}</script>

7、provide 与 inject

  • provideinject提供依赖注入,功能类似 2.x 的provide/inject

  • 实现跨层级组件(祖孙)间通信

<template><h1>父组件</h1><p>当前颜色: {{color}}</p><button @click="color='red'">红</button><button @click="color='yellow'">黄</button><button @click="color='blue'">蓝</button><hr><Son />
</template><script lang="ts">
import { provide, ref } from 'vue'
/* 
- provide` 和 `inject` 提供依赖注入,功能类似 2.x 的 `provide/inject
- 实现跨层级组件(祖孙)间通信
*/import Son from './Son.vue'
export default {name: 'ProvideInject',components: {Son},setup() {const color = ref('red')provide('color', color)return {color}}
}
</script>
<template><div><h2>子组件</h2><hr><GrandSon /></div>
</template><script lang="ts">
import GrandSon from './GrandSon.vue'
export default {components: {GrandSon},
}
</script>
<template><h3 :style="{color}">孙子组件: {{color}}</h3></template><script lang="ts">
import { inject } from 'vue'
export default {setup() {const color = inject('color')return {color}}
}
</script>

三:结尾

        熟练的掌握 Vue3 中各种组合式 api ,可以让我们在日常开发中规避很多的 bug 以及提高代码速率。好啦,以上就是本文的全部内容了。希望能够对各位小伙伴有所帮助哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/169293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

案例024:基于微信小程序的汽车保养系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

基于ThinkPHP8 + Vue3 + element-ui-plus + 微信小程序(原生) + Vant2 的 BBS论坛系统设计【PHP课设】

一、BBS论坛功能描述 我做的是一个论坛类的网页项目&#xff0c;每个用户可以登录注册查看并发布文章&#xff0c;以及对文章的点赞和评论&#xff0c;还有文件上传和个人签名发布和基础信息修改&#xff0c;管理员对网站的数据进行统计&#xff0c;对文章和文件的上传以及评论…

MobileNets发展

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 引言MobileNetsMobileNet - V1思想代码实现 MobileNet - V2思想代码实现 MobileNet - …

学习openGauss

学习openGauss 了解openGauss openGauss内核源自PostgreSQL&#xff0c;并着重在架构、事务、存储引擎、优化器等方向持续构建竞争力特性&#xff0c;在ARM架构的芯片上深度优化&#xff0c;并兼容X86架构。实现以下技术特点&#xff1a; 基于多核架构的并发控制技术、NUMA-…

基于协作搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于协作搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于协作搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于协作搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

P8873 梅莉的市场经济学

二分题目,难在对细节的把握,改起来很容易烦躁,不想改了,重在坚持,边界问题改起来确实麻烦,注意一下就可以 #include<bits/stdc.h> #include<unordered_map> #include<unordered_set> #define int int64_t using namespace std; signed main() {ios::sync_w…

elasticsearch Connection reset by peer如何处理

如何处理&#xff1a; 代码的心跳代码删除&#xff0c;服务linux内核参数修改 客户端时间要小于服务端时间#异常代码 public RestHighLevelClient elasticsearchClient() {// 初始化 RestClient, hostName 和 port 填写集群的内网 IP 地址与端口 // String[] hosts nod…

气膜厂家如何确保质量?

气膜厂家是专门生产和销售气膜产品的企业&#xff0c;需要对产品的质量进行有效管理和控制&#xff0c;以确保产品能够满足客户的需求和期望。下面将从生产过程、质量控制手段和售后服务等方面介绍气膜厂家如何确保产品质量。 起初&#xff0c;气膜厂家需要建立完善的质量管理…

MIT6.824-Raft笔记:Raft初探、副本间log时序

从宏观角度说明raft在程序中的作用&#xff0c;和客户端的关系&#xff0c;以及多个副本之间的关系&#xff1b;从微观角度说明多个副本之间raft对日志处理的流程。 1. Raft 初探 宏观角度说明raft在程序中的作用&#xff0c;和客户端的关系&#xff0c;以及多个副本之间的关…

项目环境配置 本地/测试/预发/生产

在本地目录下新建文件 dev测试环境 development 本地开发环境 production 生产环境 uat预发布环境 .env.dev VUE_APP_API_PATH /api # 测试 VUE_APP_API_PATH http:// # 生成dist名称 VUE_APP_DIST dist_dev .env.development # 本地开发环境 VUE_APP_API_PATH…

探究Kafka原理-3.生产者消费者API原理解析

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…

续新的SSL证书

一、重新申请证书并下载证书&#xff1a; https://www.ename.net/ 二、IIS中在【服务器证书】中删除旧的证书&#xff0c;导入新的证书&#xff1b; 三、在站点的绑定选择新证书&#xff1b;

力控软件与多台PLC之间ModbusTCP/IP无线通信

Modbus TCP/IP 是对成熟的 Modbus 协议的改编&#xff0c; 因其开放性、简单性和广泛接受性而在工业自动化系统中发挥着举足轻重的作用。它作为连接各种工业设备的通用通信协议&#xff0c;包括可编程逻辑控制器 (PLC)、远程终端单元 (RTU) 和传感器。它提供标准化的 TCP 接口&…

互联网时代的身份标识有哪些?

在互联网时代&#xff0c;我们的在线活动几乎都与IP地址相关。无论是浏览网页、观看视频&#xff0c;还是进行在线交易和沟通交流&#xff0c;我们的设备都会分配到一个独特的IP地址。然而&#xff0c;你可能并未意识到的是&#xff0c;IP地址不仅标识了我们在网络中的身份&…

python每日一题——5盛最多的水

题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。…

[UE4][C++]基于UUserWidget的一种序列图播放方法

最近在做一个大项目&#xff0c;鸽了几个月了....... 一、传统方法Flipbook 这种方法适合序列图较少的情况下、可以一个一个添加进来然后调整顺序。蓝图也比较友好可以直接设置很多属性和功能。这里简单了解一下即可&#xff0c;想要深入了解的同学可以自行搜索。 1.1创建Fli…

代码随想录算法训练营第17天|● 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和

110. 平衡二叉树 简单 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; [图片] 输入&#xff1a;root [3,9,20,null…

c++11新特性篇-可调用对象包装器, 绑定器

可调用对象包装器, 绑定器 可调用对象 可调用对象是指在 C 中能够像函数一样被调用的实体。它包括了多种类型的对象&#xff0c;使得它们能够像函数一样被调用&#xff0c;可以是函数、函数指针、函数对象、Lambda 表达式等。在C中&#xff0c;具有以下特征之一的实体都被认为…

Unity 讯飞 之 讯飞星火大模型的简单封装和使用(补充讯飞大模型识图功能)

Unity 讯飞 之 讯飞星火大模型的简单封装和使用&#xff08;补充讯飞大模型识图功能&#xff09; 目录 Unity 讯飞 之 讯飞星火大模型的简单封装和使用&#xff08;补充讯飞大模型识图功能&#xff09; 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、案例简单…

【外贸干货】领英客户开发与营销的六个策略方向

领英(LinkedIn)已经成为外贸营销人员&#xff0c;尤其是B2B外贸营销人员&#xff0c;一个重要且有效的社交媒体平台。 相比于其他社交媒体平台&#xff0c;领英(LinkedIn)在增加流量、产生高质量的潜在客户和建立思想领导力方面有着独有的优势。 因为领英(LinkedIn)不仅仅是获…