此篇讲解的是, 在学习状态管理之前, 非父子间通信的方案
在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信。
这里我们主要讲两种方式:
Provide/Inject;
全局事件总线;
Provide/Inject用于非父子组件之间共享数据:
对于这种情况下,我们可以使用 Provide 和 Inject :
实际上,你可以将依赖注入看作是“long range props”,除了:
我们开发一个下面这样的结构: 让App.vue提供一些数据给HomeContent.vue使用[外链图片转存失败,
在祖先组件中通过provide将数据传出, provide对应的是一个对象
export default {
components: {
Home
},
// 通过provide将数据传出
provide() {
return {
name: this.name,
age: this.age,
height: this.height
}
}
}
在后代元素中, 通过inject接收祖先传递的数据, inject对应的是一个数组
export default {
inject: ["name", "age", "height"]
}
我们先来验证一个结果:如果我们修改了this.names的内容,那么使用length的子组件会不会是响应式的?
<template>
<div class="app">
<home />
<h2>{{ name }}h2>
<button @click="btnClick">按钮button>
div>
template>
<script>
import Home from './Home.vue'
export default {
components: {
Home
},
data() {
return {
name: "chenyq",
age: 18,
height: 1.88,
}
},
// 通过provide将数据传出
provide() {
return {
name: this.name,
age: this.age,
height: this.height
}
},
methods: {
btnClick() {
this.name = "kaisa"
}
},
}
script>
我们会发现对应的子组件中是没有反应的:
这是因为当我们修改了names之后,之前在provide中引入的 this.name 本身并不是响应式的;
那么怎么样可以让我们的数据变成响应式的呢?
import { computed } from 'vue'
export default {
components: {
Home
},
data() {
return {
name: "chenyq",
age: 18,
height: 1.88,
}
},
// 通过provide将数据传出
provide() {
return {
name: computed(() => this.name),
age: this.age,
height: this.name
}
},
methods: {
btnClick() {
this.name = "kaisa"
}
},
}
注意:我们在使用name的时候需要获取其中的value
<template>
<div class="home-content">
<h2>名字: {{ name.value }}, 年龄: {{ age}}, 身高: {{ height}}h2>
div>
template>
Vue3从实例中移除了 o n 、 on、 on、off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库:
首先,我们需要先安装这个库:npm install hy-event-store
其次,我们可以封装一个工具eventbus.js:
import { HyEventBus } from "hy-event-store";
const eventBus = new HyEventBus()
export default eventBus
在项目中导入后可以使用它们:
Banner中触发事件:
<template>
<div class="home-content">
<button @click="btnClick">按钮button>
div>
template>
<script>
import eventBus from './utils/event-bus'
export default {
methods: {
btnClick() {
console.log("myEvent事件被监听")
// 发送事件到事件总线上
eventBus.emit("myEvent", "chenyq", 18, 1.88)
}
},
}
script>
App中监听事件:
<script>
import eventBus from './utils/event-bus'
import Home from './Home.vue'
export default {
components: {
Home
},
created() {
// 监听事件总线上的事件
eventBus.on("myEvent", (name, age, height) => {
console.log(name, age, height)
})
},
}
script>