依赖注入 — Provide/Inject
1.关于
对于前面所说的组件通信方式(props、emits、refs),当只有父子两级时,使用起来较为方便,但在实际的开发中,组件之间的嵌套关系往往并不止于父子两级,所以如果还选择使用前面的方式,例如props,就会导致组件的模板字面量非常的长,同时,也可能会出现各种难以预期的情况。
而这里要说的Provide和Inject就是用于解决这一问题的。
2.示例
这里用三个组件来进行演示
父级组件 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>
孙组件 grandchild:
<template>
<section class="item">GRANDCHILDREN {{num}}</section>
<grandchildren />
</template>
<script setup>
import { inject } from 'vue';
const { num } = inject('count');
</script>
此时页面的显示效果为:
PARENT 0
CHILD
GRANDCHILDREN 0
即在孙组件中可以使用由父组件传递过来的数据。
3.用法
3.1 语法解释
provide() 方法,接收两个参数:
- 第一个参数是要注入的
key,可以是一个字符串或者一个Symbol; - 第二个参数则是要注入的值
inject() 方法,可以接收三个参数:
- 第一个参数对应注入依赖的
key。 - 第二个参数是可选的,即在没有匹配到
key时使用的默认值。它可以是一个工厂函数,用于返回某些创建起来比较复杂的值。 - 第三个参数是可选的,其类型为
Boolean。当第二个参数中的默认值本身就是一个函数,但不是工厂函数时,需要将该参数置为false。
3.2 配合响应式使用
当注入的值为响应式数据时,建议尽可能将任何对响应式状态的变更都保持在provide内部。
这样的话,可以确保对该响应式数据的状态和变更操作,都在同一个组件中,使其更容易维护。
还是用前面的例子,如果需要实现在孙组件中修改num的值,则在父组件中注入时应当提供对应的修改方法:
<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++;
};
// 修改num状态的函数
const increaseNum = (params) => {
num.value += params;
};
// 将 increaseNum 函数作为值提供
provide('count', { num, increaseNum });
</script>
这样,在孙组件中,就可以通过提供的方法触发父组件中的函数,对值进行修改:
<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>
依赖注入的Provide/Inject在Vue.js中用于解决多级组件通信的问题,避免props的长链导致的复杂性。文章通过一个例子展示了如何从父组件向孙组件传递数据,强调了配合响应式使用时应保持状态变更在提供者组件内部,以简化维护。
1582

被折叠的 条评论
为什么被折叠?



