说明
【Vue 开发实战】学习笔记。
组件通信
provide/inject
底层通用组件用的很多。进行跨组件通信。
要实现组件 E 变化,更新 F、I
组件A
<template> <div class="border"> <h1>A 结点(第一级)</h1> <button @click="() => changeColor()">改变color</button> <ChildrenB /> <ChildrenC /> <ChildrenD /> </div> </template> <script> import ChildrenB from "./ChildrenB"; import ChildrenC from "./ChildrenC"; import ChildrenD from "./ChildrenD"; export default { components: { ChildrenB, ChildrenC, ChildrenD }, // provide() { // return { // theme: { // color: this.color // } // }; // }, // 需要响应式数据 provide() { return { theme: this }; }, data() { return { color: "blue" }; }, methods: { changeColor(color) { if (color) { this.color = color; } else { this.color = this.color === "blue" ? "red" : "blue"; } } } }; </script>
组件E
<template> <div class="border2"> <h3 :style="{ color: theme.color }">E 结点(第三级)</h3> <button @click="handleClick">改变color为green</button> </div> </template> <script> export default { components: {}, inject: { theme: { default: () => ({}) } }, methods: { handleClick() { if (this.theme.changeColor) { this.theme.changeColor("green"); } } } }; </script>
组件F:可以通过 from 命别名
<template> <div class="border2"> <h3 :style="{ color: theme1.color }">F 结点(第三级)</h3> </div> </template> <script> export default { components: {}, inject: { // 可以通过 from 命别名 theme1: { from: "theme", default: () => ({}) } } }; </script>
组件I:函数式组件需要使用 injections
<template functional> <div class="border2"> <!-- 函数式组件使用injections --> <h3 :style="{ color: injections.theme.color }">I 结点(第三级)</h3> </div> </template> <script> export default { inject: { theme: { default: () => ({}) } } }; </script>
点击两个按钮改变颜色,三个子节EFI点都会颜色变化
如果在组件C 里添加 provide
<template> <div class="border1"> <h2>C 结点(第二级)</h2> <ChildrenE /> <ChildrenF /> </div> </template> <script> import ChildrenE from "./ChildrenE"; import ChildrenF from "./ChildrenF"; export default { components: { ChildrenE, ChildrenF }, provide() { return { theme: { color: "green" } }; } }; </script>
EF节点不会变化,只有A节点的按钮点击了I节点才会变化颜色,这个跟冒泡很类似。就像在C节点阻止了冒泡事件一样
完整源码可以参考这个https://github.com/kaimo313/vue-development-practice/tree/master/vue-demo/src/views/demo12