前言
以下代码和内容的使用都是在setup中,未使用TS。
<script setup>
</script>
关于 Provide Inject
在组件(1)中,父子组件的传递使用的是props
的方式。当只有父子两级的时候,确实很方便。但在实际开发中,组件的嵌套关系往往更加复杂,如果还是使用props
,会使得组件的模版字面量非常的长,也会出现其他预期情况。
Provide
和 Inject
就是用来解决上面的问题。
使用
这里使用三个组件来模拟数据传递的情况:
父级 parent:
<template>
<section class="item" @click="onClick">PARENT {{ num }}</section>
<childVue /> <!-- 引入子组件 -->
</template>
<script setup>
import childVue from './child.vue';
import { ref, provide } from 'vue';
const num = ref(0);
const onClick = () => {
num.value++;
};
provide('count', { num });
</script>
子组件 child :
<template>
<section class="item">CHILD</section>
<grandchildren /><!-- 引入孙组件 -->
</template>
孙组件 grandchildren :
<template>
<section class="item">GRANDCHILDREN</section>
<grandchildren />
</template>
<script setup>
import { inject } from 'vue';
const { num } = inject('count');
</script>
这时页面会展示为
PARENT 0
CHILD
GRANDCHILDREN 0
语法解释
provide()
接受两个参数:
- 第一个参数是要注入的 key,可以是一个字符串或者一个 symbol;
- 第二个参数是要注入的值。
inject()
可以接受三个参数:
- 第一个参数是注入的 key,
- 第二个参数是可选的,即在没有匹配到 key 时使用的默认值。它也可以是一个工厂函数,用来返回某些创建起来比较复杂的值。
- 第三个参数是可选的,类型为布尔值。当第二个参数的值就是一个函数,而不是工厂函数时,需要使用将值设置为 false。
配合响应性
当使用响应式 provide/inject 值时,建议尽可能将任何对响应式状态的变更都保持在 provider 内部。这样可以确保 provide 的状态和变更操作都在同一个组件内,使其更容易维护。
如果需要在 grandchildren
中修改num的值,如点击一次加2或者更多。应当:
<template>
<section class="item" @click="onClick">PARENT {{ num }}</section>
<childVue /> <!-- 引入子组件 -->
</template>
<script setup>
import childVue from './child.vue';
import { ref, provide } from 'vue';
const num = ref(0);
const onClick = () => {
num.value++;
};
// 新增函数
const increaseNum = (params) => {
num.value += params;
};
// 将 increaseNum 函数作为值 提供
provide('count', { num, increaseNum });
</script>
孙组件 grandchildren :
<template>
<!-- 新增点击事件 -->
<section class="item" @click="onClick">GRANDCHILDREN</section>
<grandchildren />
</template>
<script setup>
import { inject } from 'vue';
// 在注入出添加 increaseNum 变量
const { num, increaseNum } = inject('count');
// 新增的点击事件,触发 increaseNum 并且传参为 2
const onClick = () => {
increaseNum(2);
};
</script>
这样在点击 grandchildren
时,父组件的触发对应的函数,num每次加2。点击父组件时,每次加1。