1. 作用
用于父组件给子孙组件传值,隔代传值也可以直接一步到位,而不用像 props 那样逐层传递
2. 用法
祖先组件中 provide('key', value)
后代组件中 let data = inject('key')
3. 案例
爷组件中
// App.vue
<template>
<h1>爷组件</h1>
<label><input type="radio" name="color" value="red" v-model="colorVar">红</label>
<label><input type="radio" name="color" value="green" v-model="colorVar">绿</label>
<label><input type="radio" name="color" value="blue" v-model="colorVar">蓝</label>
<div></div>
<hr>
<parent></parent>
</template>
<script setup lang="ts">
import { provide, ref } from 'vue';
import Parent from './components/Parent.vue' // 引入父组件并使用
let colorVar = ref<string>('red') // 定义一个变量
provide('colorVar', colorVar) // 将这个变量 provide 给后代组件
</script>
<style scoped>
div {
width: 100px;
height: 100px;
/* 小妙招:可以直接用 v-bind 绑定 setup 中定义的变量,实现 CSS 的响应式 */
background-color: v-bind(colorVar);
}
</style>
父组件中
// Parent.vue
<template>
<h2>父组件</h2>
<div></div>
<hr>
<child></child>
</template>
<script setup lang="ts">
import { inject } from 'vue';
import Child from './Child.vue' // 引入子组件并使用
let colorVar = inject('colorVar') // 接收爷组件 provide 的值
</script>
<style scoped>
div {
width: 100px;
height: 100px;
background-color: v-bind(colorVar);
}
</style>
子组件中
// Child.vue
<template>
<h3>子组件</h3>
<div></div>
</template>
<script setup lang="ts">
import { inject } from 'vue';
let colorVar = inject('colorVar') // 接收爷组件 provide 的值
</script>
<style scoped>
div {
width: 100px;
height: 100px;
background-color: v-bind(colorVar);
}
</style>
实现的效果是,爷组件中选中不同的颜色,父组件和子组件的 div 就会同步切换成对应的颜色
4. 注意
子组件中对注入值的修改也会同步影响到父爷组件的值
// Child.vue
<template>
<h3>子组件</h3>
<div></div>
<br>
<button @click="changeYellow">修改颜色为黄色</button>
</template>
<script setup lang="ts">
import { inject, ref, Ref } from 'vue';
let colorVar = inject<Ref<string>>('colorVar', ref('pink')) // 第二个参数是默认值
// let colorVar = inject<Ref<string>>('colorVar) // 没写默认值
const changeYellow = () => {
colorVar.value = 'yellow' // 如果写了默认值,则可以直接赋值
// colorVar!.value = 'yellow' // 如果没写默认值,则要写非空断言
}
</script>
<style scoped>
div {
width: 100px;
height: 100px;
background-color: v-bind(colorVar);
}
</style>
点击按钮效果如下