案例1:
假设第二层的一个组件想和第一层的大组件进行通信,这用到前面学的父子组件传值问题:
父组件通过props向子组件传值,子组件通过事件触发向父组件传值
案例2:
假设第三层的组件想和大组件进行通信,这时候该如何实现呢?
下面这种通信又改如何实现?
这就需要 非父子组件传值 来实现了
非父子组件传值
也称为发布订阅模式 / 总线机制 / Bus / 观察者模式
先看实现效果:
鼠标点击 Tony ,下面的组件Dove也变成了 Tony:
同理,鼠标点击组件2 Dove,那上面的组件 Tony 就会变成 Dove
这样就实现了兄弟组件之间的通信
代码实现:
<body>
<div id='root'>
<child content="Tony"></child>
<child content="Dove"></child>
</div>
<script>
/*
在Vue类的原型上挂一个bus属性 这个属性指向了一个Vue的实例
只要我们后面创建 new Vue 或创建组件 每一个组件上就都会有 bus这个属性
因为这里每一个组件或Vue的实例 都是通过Vue这个类来创建的 而之前我们在Vue的类上挂载了一个bus属性
每一个通过类创建的对象(Vue的实例)都会有bus这个属性,且都指向同一个Vue的实例
*/
Vue.prototype.bus=new Vue();
Vue.component('child',{
data:function(){
return {
slefContent:this.content
}
}
,
props:{
content:String
},
template:'<div @click="handleClick">{{slefContent}}</div>',
methods: {
// 子组件的methods里面 定义 handleClick方法
handleClick:function(){
/*
点击组件1 把组件1的内容 传给 组件2
this.bus指的就是 当前Vue实例上挂载的那个bus属性
*/
this.bus.$emit('change',this.slefContent);
}
},
//mounted---组件被挂载的时候会执行的函数
mounted:function(){
var this_= this;
//bus是一个Vue的实例,所以bus上就也有$on这个方法
//因此他就能监听到bus上面触发出来的事件
this.bus.$on('change',function(msg){
this_.slefContent = msg;
});
}
});
/*
在一个组件里面触发事件的时候,两个组件都进行了同一个组件的监听
所以两个child组件都会弹出msg
*/
var vm =new Vue({
el:'#root'
})
</script>
</body>