Provide / Inject
通常,当我们需要从父组件向子组件传递数据时,我们使用 props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦。
官网的解释很让人疑惑,那我翻译下这几句话:
provide 可以在祖先组件中指定我们想要提供给后代组件的数据或方法,而在任何后代组件中,我们都可以使用 inject 来接收 provide 提供的数据或方法。
代码示例
额外的知识点
// let color = inject<Ref<string>>("color", ref("red")); // 1.给一个red默认值
let change = () => {
// color?.value = "blue"; // 不能使用可选操作符? 有二种方式处理
color!.value = "blue"; // 2.非空断言 !
};
let colorVal = ref<string>("red");
background: v-bind(
colorVal
); // 在vue3中可以获取js中的变量,background-color样式不生效
顶层组件(爷爷级)
<template><!-- 可参考这个文章 --><h3>Angular依赖注入 是通过IOC控制反转和依赖注入(DI)</h3><h3>vue依赖注入provide和inject 是通过原型链</h3><div class="text">爷爷级别</div><h6>当用户点击一个单选按钮时,它就会被选中,其他同名的单选按钮就不会被选中。</h6><label><inputtype="radio"v-model="colorVal"value="yellow"name="color"/>黄色</label><label><inputtype="radio"v-model="colorVal"value="blue"name="color"/>蓝色</label><div class="box"></div><A></A>
</template><script setup lang="ts">
import {ref,reactive,watch,provide,readonly,
} from "vue";
import A from "./components/fifteen_A.vue";let colorVal = ref<string>("red");
// provide("color", readonly(colorVal)); // key value readonly约束子组件修改值
provide("color", colorVal);
watch(() => colorVal.value,(newVal) => {console.log(newVal);}
);
</script><style lang="less" scoped>
.text {color: red;
}
.box {width: 50px;height: 50px;border: 1px solid #ccc;background: v-bind(colorVal); // 在vue3中可以获取js中的变量,background-color样式不生效
}
</style>
父级组件A
<template><div class="text">父亲级别</div><div class="box"></div><B></B>
</template><script setup lang="ts">
import { ref, reactive, watch, inject } from "vue";
import B from "./fifteen_B.vue";
import type { Ref } from "vue";
//与注入provide的key保持一致,由于color推断出来的类型是unkown,由于传入的是ref,故这里需要引入Ref的泛型,再接收泛型string
// let color = inject("color");
let color = inject<Ref<string>>("color"); // 此时color推断出来的类型是: Ref<string> | undefined
</script><style lang="less" scoped>
.text {color: red;
}
.box {width: 50px;height: 50px;border: 1px solid #ccc;background: v-bind(color); // 在vue3中可以获取js中的变量,background-color样式不生效
}
</style>
孙子组件B
<template><div class="text">孙子级别</div><button @click="change">在子组件中修改provide传入的值为blue</button><div class="box"></div>
</template><script setup lang="ts">
import { ref, reactive, watch, inject } from "vue";
import type { Ref } from "vue";
let color = inject("color");
// let color = inject<Ref<string>>("color", ref("red")); // 1.给一个red默认值
let change = () => {// color?.value = "blue"; // 不能使用可选操作符? 有二种方式处理color!.value = "blue"; // 2.非空断言 !
};
</script><style lang="less" scoped>
.text {color: red;
}
.box {width: 50px;height: 50px;border: 1px solid #ccc;background: v-bind(color); // 在vue3中可以获取js中的变量,background-color样式不生效
}
</style>
效果图:
16 组件通信兄弟传参和&Bus-CSDN博客16 组件通信兄弟传参和&Bus。https://blog.csdn.net/qq_37550440/article/details/142491642?sharetype=blogdetail&sharerId=142491642&sharerefer=PC&sharesource=qq_37550440&spm=1011.2480.3001.8118