Vue3依赖注入 provide/inject

news/2024/11/17 0:32:58/

官网:https://cn.vuejs.org/guide/components/provide-inject.html

Prop 逐级透传问题

有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。如果组件链

路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”。

provideinject 可以帮助我们解决这一问题。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件

树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。

Provide (提供)

<script setup>
import { provide } from 'vue'provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
</script>// 不使用 <script setup>
import { provide } from 'vue'export default {setup() {provide(/* 注入名 */ 'message', /* 值 */ 'hello!')}
}

第二个参数是提供的值,值可以是任意类型,包括响应式的状态,比如一个 ref:

import { ref, provide } from 'vue'const count = ref(0)
provide('key', count)

应用层 Provide

除了在一个组件中提供依赖,我们还可以在整个应用层面提供依赖

import { createApp } from 'vue'const app = createApp({})app.provide(/* 注入名 */ 'message', /* 值 */ 'hello!')

在应用级别提供的数据在该应用内的所有组件中都可以注入。这在你编写插件时会特别有用,因为插件一般都不会使用组

件形式来提供值。

Inject (注入)

<script setup>
import { inject } from 'vue'const message = inject('message')// 如果没有祖先组件提供 "message"
// `value` 会是 "这是默认值"
const value = inject('message', '这是默认值')
</script>

如果提供的值是一个 ref,注入进来的会是该 ref 对象,而不会自动解包为其内部的值。这使得注入方组件能够通过 ref 对象

保持了和供给方的响应性链接。

// 不使用 <script setup>
import { inject } from 'vue'export default {setup() {const message = inject('message')return { message }}
}

在一些场景中,默认值可能需要通过调用一个函数或初始化一个类来取得。为了避免在用不到默认值的情况下进行不必要的计

算或产生副作用,我们可以使用工厂函数来创建默认值:

const value = inject('key', () => new ExpensiveClass())

和响应式数据配合使用

当提供 / 注入响应式的数据时,建议尽可能将任何对响应式状态的变更都保持在供给方组件中。这样可以确保所提供状态的声

明和变更操作都内聚在同一个组件内,使其更容易维护

有的时候,我们可能需要在注入方组件中更改数据

在这种情况下,我们推荐在供给方组件内声明并提供一个更改数据的方法函数

<!-- 在供给方组件内 -->
<script setup>
import { provide, ref } from 'vue'const location = ref('North Pole')function updateLocation() {location.value = 'South Pole'
}provide('location', {location,updateLocation
})
</script>
<!-- 在注入方组件 -->
<script setup>
import { inject } from 'vue'const { location, updateLocation } = inject('location')
</script><template><button @click="updateLocation">{{ location }}</button>
</template>

最后,如果你想确保提供的数据不能被注入方的组件更改,你可以使用 readonly() 来包装提供的值。

<script setup>
import { ref, provide, readonly } from 'vue'const count = ref(0)
provide('read-only-count', readonly(count))
</script>

使用 Symbol 作注入名(避免潜在的冲突)

在一个单独的文件中导出这些注入名 Symbol:

// keys.js
export const myInjectionKey = Symbol()
// 在供给方组件中
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'provide(myInjectionKey, { /*要提供的数据
*/ });
// 注入方组件
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'const injected = inject(myInjectionKey)

http://www.ppmy.cn/news/724846.html

相关文章

B与BL

b与bl指令的作用是什么&#xff1f; b与bl指令的作用&#xff1a;实现程序跳转&#xff0c;也就是调用子程序。 b与bl指令的区别是什么&#xff1f; b与bl指令的区别&#xff1a;b指令&#xff1a;简单的程序跳转&#xff0c;跳转到到目标标号处执行。 bl指令&#xff1a;带链…

ASBU(Aviation System Block Upgrade, 民航系统组件升级)的机场运行领域的模块B0-APTA介绍500字...

ASBU(Aviation System Block Upgrade)是一种民航系统组件升级方案&#xff0c;主要用于提高机场的运行效率和安全性。B0-APTA模块是ASBU的一部分&#xff0c;主要用于支持机场短期规划和调度。 B0-APTA模块包括以下功能&#xff1a; 机场规划与调度&#xff1a;支持机场的短期规…

B- B+

B 树 即二叉搜索树&#xff1a; 1. 所有非叶子结点至多拥有两个儿子&#xff08; Left 和 Right &#xff09;&#xff1b; 2. 所有结点存储一个关键字&#xff1b; 3. 非叶子结点的左指针指向小于其关键字的子树&#xff0c;右指针指向大于其关键字的子树&#xff1b; 如…

A/B

要求(A/B)%9973&#xff0c;但由于A很大&#xff0c;我们只给出n(nA%9973)(我们给定的A必能被B整除&#xff0c;且gcd(B,9973) 1)。 Input 数据的第一行是一个T&#xff0c;表示有T组数据。 每组数据有两个数n(0 < n < 9973)和B(1 < B < 10^9)。 Output 对应每组数…

bzero

原型&#xff1a; extern void bzero&#xff08;void * s&#xff0c;int n&#xff09; 函数说明&#xff1a;bzero()会将参数s 所指的内存区域前n 个字节&#xff0c;全部设为零值。 附加说明&#xff1a;添加头文件<strings.h>&#xff0c;bzero()不是ANSI C函数&am…

B0M

&#xfeff;&#xfeff; &#xff08;一&#xff09;screen对象&#xff0c;Screen 对象中存放着有关显示浏览器屏幕的信息。 常见的属性有&#xff1a; availHeight:返回显示屏幕的高度 availWidth:返回显示屏幕的宽度 colorDepth:返回目标设备或缓冲器上的调色板的比特…

a//b

python中&#xff0c;/ 表示浮点数除法&#xff0c;//表示整数除法&#xff0c;返回不大于结果的一个最大整数 &#xff08;第一次遇到的时候上网查找&#xff0c;没加关键词python&#xff0c;结果就真的没找到什么含义&#xff0c;汗&#xff09;

a + b + c = 0

给一个包含 n 个整数的数组 nums&#xff0c; 判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c; 使得 a b c 0 &#xff1f;请你找出所有和为 0 且不重复的三元组。 function sumZero(nums){nums new Set(nums);nums [...nums];var sum [];if(nums…