父子组件的通信已经知道了,但是在实际的项目中如果需要拿到兄弟组件上的数据(非父子)那该如何是好呢?
其实Vue已经为我们提供了一套解决方案:使用中央事件总线;
非父子组件间的通信,使用一个空的Vue实例来作为中央事件总线(就相当于中介一样),用它来抛出和监听事件
1.定义一个空的Vue实例var bus= new Vue()作为中央事件总线(bus);
2.在发送数据的组件中使用bus.$emit("事件名",要发送数据),来扔出一个事件(连带着数据,数据可以有多个,用逗号分隔);
3.在接收数据的组件中使用bus.$on("事件名",callback)来监听扔出来的事件,在callback中可以传入参数(可以有多个)用来接收数据(一般写在生命周期mounted阶段中);
注意:在定义一个新的Vue实例作为事件总线的时候,一般要写在非空Vue实例的前面;防止在接收数据的的组件已经完成编译的时候,事件总线还没定义。。。,例如:
HTML部分
<div id="container" v-cloak>
<my-compo></my-compo>
<your-compo></your-compo>
</div>
<!-- 组件一 -->
<template id="myCompo">
<div>
<h3>我有一个{{shoe.color}}的鞋子,价格是{{shoe.size}}元</h3>
<button @click = "sendData">点击发送数据</button>//点击执行sendData方法,来向外抛出一个自定义事件
</div>
</template>
<!-- 组件二 -->
<template id="yourCompo">
<div>
<h3>他开着一辆价值{{car.price}}的{{car.color}}的{{car.brand}}疾驰而去</h3>
<hr>
<h2>我是来自兄弟组件my-compo中的数据{{price}},{{size}}</h2>
</div>
</template>
JS部分
// 中央事件总线;空的vue实例
var bus = new Vue()
// Vue实例
var app = new Vue({
el:"#container",
data:{
person:{
weight:120,
sex:"男",
country:"中国"
},
book:"《时间简史》"
},
components:{
"my-compo":{//组件1
template:"#myCompo",
data:function(){
return {
shoe:{
color:"红色",
size:43,
price:"120"
}
}
},
methods:{
sendData:function(){
bus.$emit("mylla",this.shoe.price,this.shoe.size)//抛出一个事件,携带一些数据
}
}
},
"your-compo":{//组件2,和组件1互为兄弟组件
template:"#yourCompo",
data:function(){
return {
car:{
brand:"宝马7系",
price:"120万",
color:"黑色"
},
price:"",
size:""
}
},
mounted:function(){//生命周期,当模板编译完时执行
var that = this;//这里的this代表的时当前组件实例本身
bus.$on("mylla",function(data1,data2){//由bus来监听自定义事件的抛出,一旦监听到了就会执行callback函数
that.price = data1;
that.size = data2
//这里的this指的是bus本身,因为在这里相当于是事件的监听,对于事件监听而言,谁在监听事件this就代表谁
})
}
}
}
})