vue3中的provide/inject(提供注入)
在说provide/inject 先说一下prop逐级穿透问题。
通常我们从父组件向子组件传递数据时,会用到props 。对于只需要传递一层或二层时还行,假如需要传递多层嵌套的组件,此时一级一级传递数据就会很繁琐,不利于编码,因此产生了provide/inject ,从而解决此类问题。
有了provide/inject 不用一级一级传递,只要是父组件提供了某个数据,隔代组件就能直接获取都数据,从而很方便。
provide()提供
为后代组件提供数据
import { provide } from 'vue';
export default {
setup() {
provide('message', 'hello!');
}
}
接受两个参数,第一个参数称为注入名,也就是key,可以是字符串或者Symbol。第二个参数是值,要传递的数据,任意类型的数据。
应用层的provide()
传递的数据,整个实例的组件都能使用。
例如:
import { createApp } from 'vue'
const app = createApp({})
app.provide('message', 'hello!')
Inject()注入
用来接收provide 传递过来的数据
参数是注入名,也就是key。
<script setup>
import { inject } from 'vue'
const message = inject('message')
</script>
如果提供的值是一个 ref,注入进来的会是该 ref 对象,不会自动解包为其内部的值,具有响应式。
注入默认值
就是key可能并没有任何父组件提供,而却注入此时就会发生错误,这个时候可以设置一个默认值。
const value = inject('message', '这是默认值')
和响应式数据配合使用
意思是加入注入组件想操作注入的数据的时候,尽可能的使其操作在父组件内,这样声明和变更操作都在父组件内,更容易维护。
<!-- 在父组件内 -->
<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作为注入名,可以避免注入名冲突。
例如:
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)
|