欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > vue3中 provide/inject用法详解

vue3中 provide/inject用法详解

2024/11/30 14:40:04 来源:https://blog.csdn.net/weixin_44180579/article/details/140867145  浏览:    关键词:vue3中 provide/inject用法详解

依赖注入:provide 和 inject

什么情况下推荐provide/inject使用:Prop 多层级数据透传

通常情况下,当我们需要从父组件向子组件传递数据时,会使用 props。想象一下这样的结构:有一些多层级嵌套的组件,形成了一棵巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦:

在这里插入图片描述
上图方式,数据传递,只会一级一级的向下传递,如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况

provide 和 inject 可以帮助我们解决这一问题

一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖

在这里插入图片描述
Provide (提供)

provide() 函數接收兩個參數 provide(注入名,注入值)

<script setup>
import { provide } from 'vue'provide(/* 注入名 */ 'message', /* 值 */ 'hello!')//例子
provide('message', 'hello!')
</script>

第一個參數被稱為注入名,可以是一個字符串或是一個Symbol。後代組件會用注入名來查找期望注入的值。一个組件可以多次调用 provide(),使用不同的注入名,注入不同的依赖值。

第二個參數是提供的值,值可以是任意类型,包括响应式,比如一個 ref

import { ref, provide } from 'vue'const count = ref(0)
provide('key', count)
provide全局注入
// main.ts页面
import { createApp } from 'vue'const app = createApp({})app.provide('message', 'hello!')  //全局注入一个message数据//所有組件中都可以获取到注入的message数据
使用 Symbol 作注入名

什么情况下使用 Symbol 作为注入名:大型的应用,包含非常多的依赖提供,或者你正在编写提供給其他开发者使用的组件库

const myInjectionKey = Symbol()
provide(myInjectionKey, { /*要提供的数据*/ });const injected = inject(myInjectionKey)

Inject (注入)

获取 provide注入数据的方法

<script setup>
import { inject } from 'vue'const message = inject('message')console.log('message', message)  //输出 hello!
</script>

注意:如果提供的值是一个 ref,注入进来的会是该 ref 对象,而不会自动解包为其內部的值(注入进来是什么类型,接收的就是什么类型)

inject 设置接收默认值

//如果注入的message为空的话 value会是默认的值  XXXXXX
const value = inject('message', 'XXXXXX')

在一些场景中,默认值可能需要通过调用一个函数或初始化一个类来取得

const value = inject('key', () => new ExpensiveClass(), true)//第三个参数表示默认值应该被当作一个工厂函数

配合响应式数据使用

当提供 / 注入响应式的数据时,建议尽可能將任何对响应式状态的变更都保持在提供方組件中

<!-- 在供給方組件/父组件內 -->
import { provide, ref } from 'vue'const location = ref('North Pole')function updateLocation() {location.value = 'South Pole'
}provide('location', {location,updateLocation
})
<!-- 在注入方組件/子组件内 -->
<script setup>
import { inject } from 'vue'const { location, updateLocation } = inject('location')
</script><template>// 点击 updateLocation方法,可以调用父组件的updateLocation方法,从而更改 location 的值<button @click="updateLocation">{{ location }}</button>
</template>

如果你想确保提供的数据不能被(注入方组件/子组件)修改,可以使用 readonly() 来包裝提供的值

// readonly() 只读
const count = ref(0)provide('read-only-count', readonly(count))

具体参考: https://zh-hk.vuejs.org/guide/components/provide-inject.html#prop-drilling

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com