今天面试被问到这个问题,我自己思考的是让父组件做两个子组件之间的桥梁,但是我并没有去说,感觉是有些low啊,面试完了赶紧查查是怎么通信的;
就是我自己设想的这种方法也是解决问题的一种方法;
在Vue中实现兄弟组件的通讯也有几种方法,其中一种方法是让父组件允当两个子组件之间的中间件(中继);
另一种就是使用EventBus(事件总线),它允许两个子组件之间直接通讯,而不需要涉及父组件。
这里就要好好了解下EventBus(事件总线)的概念了;
先来看第一个方法,就是让兄弟组件通过一个共同的父组件彼此通讯。
我们还是通过示例来学习。接下来的这个示例包含父组件和两个子组件,这两个子组件是兄弟组件。单击兄弟组件上的按钮,可以看到他们之间可以相互通讯。

首先创建ParentCard组件:
<!-- ParentCard.vue -->
<template>
<div class="card">
<div class="card-header">
<h5 v-text="theCardTitle"></h5>
<button @click="momSaidChill" v-if="stopFighting()" class="btn">停止通讯</button>
</div>
<div class="card-body">
<brother-card :messageSon="messageson" @brotherSaid="messageDaughter($event)"></brother-card>
<sister-card :messageDaughter="messagedaughter" @sisterSaid="messageSon($event)"></sister-card>
</div>
</div>
</template>
<script>
import BrotherCard from ‘./BrotherCard‘;
import SisterCard from ‘./SisterCard‘
export default {
name: ‘ParentCard‘,
data: () => ({
theCardTitle: ‘父组件‘,
messagedaughter:‘‘,
messageson:‘‘
}),
components: {
BrotherCard,
SisterCard
},
methods: {
messageDaughter(message) {
this.messagedaughter = message;
},
messageSon(message) {
this.messageson = message;
},
stopFighting() {
if (this.messagedaughter && this.messageson) {
return true
}
return false
},
momSaidChill() {
this.messagedaughter = ‘‘,
this.messageson = ‘‘
}
}
};
</script>
创建SisterCard组件:
<!-- SisterCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Sister组件</p>
<button @click="messageBrother" class="btn">给哥哥发消息</button>
<div v-if="messageDaughter" class="alert" v-html="messageDaughter"></div>
</div>
</div>
</template>
<script>
export default {
name: ‘SisterCard‘,
props: [‘messageDaughter‘],
data: () => ({
theCardTitle: ‘子组件2‘
}),
methods: {
messageBrother() {
this.$emit(‘sisterSaid‘, ‘妈妈说,该做作业了!(^_^)!!!‘)
}
}
}
</script>
接着创建BrotherCard组件:
<!-- BrotherCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Brother组件</p>
<button @click="messageSister" class="btn">给妹妹发消息</button>
<div v-if="messageSon" class="alert" v-html="messageSon"></div>
</div>
</div>
</template>
<script>
export default {
name: ‘BrotherCard‘,
props: [‘messageSon‘],
data: () => ({
theCardTitle: ‘子组件1‘
}),
methods: {
messageSister() {
this.$emit(‘brotherSaid‘, ‘妈妈说,该做作业了!(^_^)!!!‘)
}
}
}
</script>
最终效果如下:
接下来简单看看这个实现过程。
SisterCard通过ParentCard与BrotherCard通讯
首先来看SisterCard是如何与BrotherCard通讯的。从示例中可以看出,他们两之间的通讯是通过其父组件ParentCard作为中间媒介来进行通讯的。
我们在SisterCard组件的<template>中为messageBrother()方法设置了一个@click事件来监听该事件。
<button
methods: {
messageBrother() {
this.$emit("sisterSaid", "妈妈说,该做作业了!(^_^)!!!");
}
}
在ParentCard的<template>中定制了一个@sisterSaid事件侦听器,它触发了messageSon()方法。所以父组件在这两个兄弟组件之间起到了传递的作用。
<sister-card :messageDaughter="messagedaughter" @sisterSaid="messageSon($event)"></sister-card>
另外在ParentCard组件中声明了messageSon()方法,该方法接受上面发送的自定义事件,并将其设置为messageson属性。
这样一来,ParentCard组件中messageson就由空字符串变成了妈妈说,该做作业了!(^_^)!!!。
接着在ParentCard组件自定义标签<brother-card>通过:messageSon="messageson"的方式将messageson属性绑定到<brother-card>。
<brother-card :messageSon="messageson" @brotherSaid="messageDaughter($event)"></brother-card>
这个时候在BrotherCard组件中设置props的属性值为messageSon。这样就可以访问源自于SisterCard组件的数据,并且该数据在BrotherCard中显示。
props: ["messageSon"],
最后在BrotherCard组件就可以使用该数据。我们可以通过v-if指令来查看messageSon是否有任何有用的数据,如果有,那么就在div.alert中显示该消息:
<div v-if="messageSon" class="alert" v-html="messageSon"></div>
上面的描述过程也适用于BrotherCard通过ParentCard与SisterCard进行数据通讯。
随着应用程序越来越庞大,通过父组件来传递所有内容会把事情变得越来越棘手。不过我们还有另一种选择,那就是使用EventBus架起兄弟之间通讯的桥梁。接下来看看我们是如何利用这一点一完成兄弟组件之间的数据通讯。
我们同样基于上面的示例来做修改。接下来的示例中,ParentCard组件包含了SisterCard和BrotherCard两个子组件,而且这两个子组件是兄弟组件。
首先在main.js文件中定义一个新的eventBus对象,其实他是一个全新的Vue实例:
// main.js
import Vue from ‘vue‘
import App from ‘./App‘
export const eventBus = new Vue()
new Vue({
el: ‘#app‘,
render: h => h(App)
})
接着在新创建的BrotherCard组件导入main.js:
<!-- BrotherCard.vue -->
<script>
import { eventBus } from ‘../main‘
</script>
eventBus实例现在将成为BrotherCard组件中发出事件的实例。现在我们可以使用eventBus.$emit来替代上例中的this.$emit。eventBus是一个Vue实例,而且eventBus有这个$emit方法,这就是我们能够这么用的原因。这样做同样会触发相同的自定义事件名称和消息。
methods: {
messageSister() {
eventBus.$emit(‘brotherSaid‘, ‘妈妈说,该做作业了!(^_^)!!!‘)
}
}
同样可以在SisterCard组件中引入eventBus:
<script>
import { eventBus } from ‘../main‘
</script>
将created()生命周期钩子添加到SisterCard组件。在created()钩子中添加eventBus启动自定义事件的侦听器。当使用SisterCard组件时,该侦听器将开始运行并且会保持运行。下面的代码只是侦听brotherSaid自定义事件,然后触发回调,将作为自定义事件有效负载传递的消息分配给fromBrother。
created() {
eventBus.$on(‘brotherSaid‘, (message) => {
this.fromBrother = message
})
}
这样就可以有条件地显示来自BrotherCard的信息:
<div v-if="fromBrother" class="alert" v-html="fromBrother"></div>
上面看到的是如何通过eventBus实现SisterCard向BrotherCard传递数据的方式,反之,BrotherCard向SisterCard`传递数据也可以使用类似的方式。
最终代码如下:
<!-- SisterCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Sister组件</p>
<button @click="messageBrother" class="btn">给哥哥发消息</button>
<div v-if="fromBrother" class="alert" v-html="fromBrother"></div>
</div>
</div>
</template>
<script>
import { eventBus } from "../main";
export default {
name: "SisterCard",
data: () => ({
theCardTitle: "Sister Card",
fromBrother: ""
}),
methods: {
messageBrother() {
eventBus.$emit("sisterSaid", "妈妈说,该做作业了!(^_^)!!!");
}
},
created() {
eventBus.$on("brotherSaid", message => {
this.fromBrother = message;
});
}
};
</script>
<!-- BrotherCard.vue -->
<template>
<div class="message">
<div class="message-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="message-body">
<p class="message-text">我是Brother组件</p>
<button @click="messageSister" class="btn">给妹妹发消息</button>
<div v-if="fromSister" class="alert" v-html="fromSister"></div>
</div>
</div>
</template>
<script>
import { eventBus } from "../main.js";
export default {
name: "BrotherCard",
data: () => ({
theCardTitle: "Brother Card",
fromSister: ""
}),
methods: {
messageSister() {
eventBus.$emit("brotherSaid", "妈妈说,该做作业了!(^_^)!!!");
}
},
created() {
eventBus.$on("sisterSaid", message => {
this.fromSister = message;
});
}
};
</script>
最后创建的ParentCard组件,我们可以像下面这样编码:
<!-- ParentCard -->
<template>
<div class="card">
<div class="card-header">
<h5 v-text="theCardTitle"></h5>
</div>
<div class="card-body">
<brother-card></brother-card>
<sister-card></sister-card>
</div>
</div>
</template>
<script>
import BrotherCard from "./BrotherCard";
import SisterCard from "./SisterCard";
export default {
name: "ParentCard",
data: () => ({
theCardTitle: "Parent Card"
}),
components: {
BrotherCard,
SisterCard
}
};
</script>
在本教程中,我们学习了在Vue中如何实现组件之间的通讯。通过实例看到了如何实现父组件向子组件,子组件向父组件以及兄弟组件间的数据通讯。简单的根据为:
props可以实现父组件向子组件发送数据eventBus来让兄弟之间组件进行数据通讯最后用一张图来简单的描述一下:

原文: https://www.w3cplus.com/vue/component-communication.html
ps:希望大家早日成为前端大神,哈哈哈
原文:https://www.cnblogs.com/zhilu/p/13851827.html