通常情况下,需要从父组件传值到子组件使用props足以,但是如果是深层嵌套的组件,如果某个深层的组件想要得到祖先组件的部分数据,使用props的话需要沿着各个嵌套的组件着层传递数据,而在传递过程中的组件压根就不需要使用该数据,这些组件只是传递的一环,如果嵌套很深,这种传递数据的方式会很麻烦
通过provide(提供)/inject(注入)就能解决这个问题,父组件相对于其所有的后代组件,作为依赖的提供者,需要使用父组件数据的后代组件,无论嵌套多深都可以注入由父组件提供给整条链路的依赖,从而获取到父组件的数据
父组件提供provide(提供)
<script setup>
import {provide } from 'vue';
import inject from './components/inject.vue';
provide('key', '父组件注入的值');
</script>
<template>
<inject />
</template>
子组件
<script setup>
import myButton from './myButton.vue'
</script>
<template>
<myButton/>
</template>
<style>
.fancy-btn {
color: #fff;
background: linear-gradient(315deg, #42d392 25%, #647eff);
border: none;
padding: 65px 50px;
margin: 5px;
border-radius: 8px;
cursor: pointer;
}
</style>
孙组件中inject(注入)
如果在注入一个值时不要求必须有提供者,那么我们应该声明一个默认值,和 props 类似
<script setup>
defineOptions({
inheritAttrs: false
})
import {inject } from 'vue';
// const key = inject('key', 'defaultvalue'); 默认值
const key = inject('key');
</script>
<template>
<div class="btn-box">
<button v-bind="$attrs">{{key}}</button>
</div>
</template>
与响应式数据配合使用及传递多个值
父组件
<script setup>
import {provide } from 'vue';
import inject from './components/inject.vue';
let prvideMsg = ref('提供者提供的数据')
function updateActiveMsg() {
prvideMsg.value = "父组件更新提供的数据";
}
// 提供多个值的话,就用一个对象来包含所有值
provide('provideData',{
key: '父组件注入的值',
activeMsg: prvideMsg,
updateActiveMsg
})
</script>
<template>
<inject />
</template>
孙组件
当点击按钮的时候会调用祖先组件提供的更新事件
<script setup>
defineOptions({
inheritAttrs: false
})
import {inject } from 'vue';
const {key, activeMsg, updateActiveMsg} = inject('provideData');
</script>
<template>
<div class="btn-box">
孙组件
<button v-bind="$attrs" @click="updateActiveMsg">{{activeMsg}}------{{key}}</button>
</div>
</template>
点击前
点击后
通过Symbol提供独一无二的注册名
新建injectedKeys文件夹用于导出注入名Symbol
export const myInjectedKey = Symbol();
依赖提供方
<script setup>
import {provide } from 'vue';
import inject from './components/inject.vue';
import {myInjectedKey } from './assets/js/privideKeys.js'
let prvideMsg = ref('提供者提供的数据')
// provide('key', '父组件注入的值');
// provide('activeMsg', prvideMsg)
function updateActiveMsg() {
prvideMsg.value = "父组件更新提供的数据";
}
// 提供多个值的话,就用一个对象来包含所有值
provide(myInjectedKey,{
key: '父组件注入的值',
activeMsg: prvideMsg,
updateActiveMsg
})
</script>
注入方组件
<script setup>
import {inject } from 'vue';
import {myInjectedKey } from '../assets/js/privideKeys.js'
const {key, activeMsg, updateActiveMsg } = inject(myInjectedKey);
</script>