Vue3关于 provide、inject 的用法
- 一、传递变量/数据
- 二、传递函数
前言:
在父子组件传递数据时,通常使用的是 props 和 emit。
父传子时,使用的是 props,如果是父组件传孙组件时,就需要先传给子组件,子组件再传给孙组件,如果多个子组件或多个孙组件使用时,就需要传很多次,会很麻烦。
像这种情况,可以使用 provide 和 inject 解决这种问题,不论组件嵌套多深,父组件都可以为所有子组件或孙组件提供数据,父组件使用 provide 提供数据,子组件或孙组件 inject 注入数据。同时兄弟组件之间传值更方便。
用一个案例来讲解
1、画绿色框框的是子组件,也就是定义在src/components中的公共部品
2、截图中其余部分为父页面,也就是定义在src/views中的业务画面
需求下拉勾选库区后,下拉框的值显示在子页面。但是“重置”按钮在父页面。要求点击“重置”按钮可以将子页面的"库区选择"清空
一、传递变量/数据
provide和inject就可以理解成是用provide发,用inject接收。
provide和inject都需要从Vue中导入,可以在main.js中全局导入,也可以在单页面中导入。
下方代码为最上方的案例
父页面(cs-select-tree就是子组件)
<template>
<el-row>
<el-form :model="state.queryForm" ref="queryRef" :inline="true">
<cs-select-tree v-model:spaceList="spaceList"></cs-select-tree>
<el-form-item>
<el-button icon="search" type="primary" @click="searchAction()">
{{ $t('common.queryBtn') }}
</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-button type="primary" class="ml10" icon="Remove" @click="cancelAction()" :disabled="multiple">
{{ '取消' }}
</el-button>
</div>
</el-row>
</template>
<script setup lang="ts" >
// 搜索变量
const spaceId = ref();
//provide('给inject的传递标记', 传递的变量/数据);
//'传递标记'就是子页面用inject注册时的标记
//若传递的是响应式数据(此示例中的spaceId就是),那么在父页面改变响应数据时,子页面的也会跟着变。
provide('provideSpaceId', spaceId);
// 清空搜索条件
const resetQuery = () => {
spaceId.value = '';
};
</script>
子组件
<template>
<el-form-item label="库区选择" class="search-tree-select">
<el-tree-select
v-model="storeSpaceId"
:data="storeTree"
:render-after-expand="false"
:check-strictly="false"
show-checkbox
multiple
class="w100"
placeholder="请选择"
ref="treeRef"
@check-change="getCheckedNodes"
>
</el-tree-select>
</el-form-item>
</template>
<script setup lang="ts" name="csSelectTree">
const emit = defineEmits(['update:spaceList']);
import { getStoreLinkList } from '/@/api/basic/store';
//定义变量
const storeTree = ref<any[]>([]);
const treeRef = ref();
//inject('provide的传递标记', '可省略,用于没有provide没传值时的默认值,因为组件可能会被多个页面调用,但并不是所有页面都需要provide')
const storeSpaceId = inject('provideSpaceId', '');
</script>
二、传递函数
父页面
const num = ref(0);
const add = () => {
num.value++;
};
provide('provideNum', num);
provide('provideAdd', add);
子页面
<div>
{{ '数据是' + num }}
<el-button @click="add()">加加加</el-button>
</div>
const num = inject('provideNum', 0);
const add = inject('provideAdd', () => {});