5.5 provide 和 inject
前面的知识告诉我们vue中组件之间传递值需要使用props来完成,但是props也有一定局限性。这个时候在vue3中还有另外的解决方法。那就是使用 provide 和 inject 允许父组件将数据传递给所有后代组件,而不管组件层次结构有多深。你要做的很简单,就是将父组件中定义的数据直接传递给它后代组件,而不需要“props drilling”。
第一章 Vue3项目创建 1 Vue CLI 创建vue项目
第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
第一章 Vue3项目创建 3 Vite 创建 vue项目
第二章 Vue3 基础语法指令
第三章 Vue Router路由器的使用
第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
第五章 Vue 组件应用 1( Props )
第五章 Vue 组件应用 2 ( Emit )
第五章 Vue 组件应用 3( Slots )
第五章 Vue 组件应用 4 ( provide 和 inject )
第五章 Vue 组件应用 5 (Vue 插件)
Props 可用于将数据从父组件传递到子组件。但是,如果从父组件到子组件传递数据的层次很深,使用props就很麻烦了。通过使用 Provide/Inject 而不是 props这种情况,可以自接将数据从父组件传递下面比使用 props 的情况方便很多。
从图形上看,Provide/Inject 和 props 之间的区别是使用Provide/Inject可以将数据直接从父组件向孙组件传递,无需经过子组件。
在项目components目录中创建zht1.vue和zht2.vue两个组件,在App.vue组件导入zht1.vue组件样zht1.vue成为App.vue组件的子组件,在zht1.vue中导入zht2.vue组件样zht2.vue成为zht1.vue的子组件。
App.vue如下内容
<script setup>
import { ref,provide } from 'vue';
import zht1 from './components/zht1.vue';
provide('mesg', 'Provide/Inject 中的信息内容');
</script>
<template>
<h1>父组件</h1>
<zht1 />
</template>
zht1.vue如下内容
<script setup>
import zht2 from './zht2.vue';
</script>
<template>
<h1>子组件</h1>
<zht2 />
</template>
zht2.vue如下内容
<script setup>
import { inject } from 'vue';
const mesg = defineProps(['mesg']);
const mesg2 = inject('mesg');
</script>
<template>
<h1>孙组件</h1>
<p>{{ mesg }}</p>
<p>{{ mesg2 }}</p>
</template>
用浏览器查看,会显示在孙组件中指定的字符串。
1 子组件中更新父组件参数值
Inject 中获得的参数值无法在子组件中直接更新 。Provide/Injdect 中可以传递函数作为参数,在子组件中使用这个函数来更新Inject 的数据值。
在 App.vue 中定义一个反应变量 count 和一个累加 addCount函数,这个累加函数负责累加count 变量。addCount函数和coun属性一样装入provide函数中。
<script setup>
import { ref,provide } from 'vue';
import zht1 from './components/zht1.vue';
provide('mesg', 'Provide/Inject 中的信息内容');
const count = ref(0);
//累加函数
const addCount = () => {
count.value++;
};
provide('count', count);
provide('addCount', addCount);//装入函数
</script>
<template>
<h1>父组件</h1>
<zht1 />
</template>
zht2.vue中使用 inject 函数获取 count 和 addCount。
<script setup>
import { inject } from 'vue';
const mesg = inject('mesg');
const count = inject('count');
const addCount = inject('addCount');
</script>
<template>
<h1>孙组件</h1>
<p>{{ mesg }}</p>
<p>Count:{{ count }}</p>
<button @click="addCount">Count累加+1</button>
</template>
当单击该按钮时,可以看到计数数字随着每次单击而增加。
2 Provide/Injdect中传递对象
在App.vue中的 Provide 函数中分别设置了变量 count 和函数 addCount ,但我们可以将它们装入一个对象中。
<script setup>
import { ref,provide } from 'vue';
import zht1 from './components/zht1.vue';
provide('mesg', 'Provide/Inject 中的信息内容');
const count = ref(0);
const addCount = () => {
count.value++;
};
//传递对象
provide('count', {
count,
addCount,
});
</script>
<template>
<h1>父组件</h1>
<zht1 />
</template>
在zht2.vue组件中,我们使用inject接收count的对象,使用解构函数提取count和addCount的引用。
<script setup>
import { inject } from 'vue';
const mesg = inject('mesg');
const { count, addCount } = inject('count');
</script>
<template>
<h1>孙组件</h1>
<p>{{ mesg }}</p>
<p>Count:{{ count }}</p>
<button @click="addCount">Count累加+1</button>
</template>