分类:
1)兄弟组件
2)跨多级组件
实现方式
Vue.js 1.X
1)在Vue.js 1.X中,除了
e
m
i
t
(
)
方
法
外
,
还
提
供
了
emit()方法外,还提供了
emit()方法外,还提供了dispatch()和
b
r
o
a
d
c
a
s
t
(
)
这
两
个
方
法
。
broadcast()这两个方法。
broadcast()这两个方法。dispatch()用于向上级派发事件,只要它的父极(一级或多级以上),都可以在Vue实例的events选项内接收
2) 核心代码
<div id="app" >
{{ message }}
<my-component></my-component>
</div>
Vue.component('my-component',{
template: '<button @click="handleDispatch">派发事件</button>',
methods: {
handleDispatch () {
this.$emit('on-message','来自组件my-component')
}
}
})
var app = new Vue({
el:'#app',
data: {
message: ''
},
events: {
'on-message': function(msg) {
this.message = msg
}
}
同理,$broadcast() 是由上级向下级广播事件的,用法完全一致,只是方向相反。
这两种方法一旦触发事件后,任何组件都可以接收到,就近原则,而且会在第一次接收后停止冒泡,除非返回true。
但是这两种方式在Vue.js 2.X中都废弃了,因为基于组件树结构的事件流方式让人难以理解,并且在组件结构扩展的过程中都会变得越来越脆弱,并且不能解决兄弟组件的通信问题。
Vue.js 2.X
1)理解:可以比喻为找中介买房子,中介联系合适的房源,买家和卖家(两个跨级的组件)没有任何交流都是通过中间人(中央事件总线–bus)传话。
2)核心代码
<div id="app" >
{{ message }}
<my-component></my-component>
</div>
var bus = new Vue();
Vue.component('my-component',{
template: '<button @click="handleEvent">传递事件</button>',
methods: {
handleEvent () {
bus.$emit('on-message','来自组件my-component')
}
}
})
var app = new Vue({
el:'#app',
data: {
message: ''
},
mounted() {
var _this = this;
bus.$on('on-message', function (msg) {
_this.message = msg;
})
},
})
3)页面效果
before:
after:
4)分析
首先创建了一个名为bus的空Vue实例,里面没任何内容;然后全局定义了组件
my-component,最后创建Vue的实例app,在app初始化时,也就是在生命周期mounted钩子函数里监听了来自bus的事件on-messsage,而在组件my-component中,点击按钮会通过bus把事件on-message发出去,此时app就会接收到来自bus的事件,进而在回调里完成自己的业务逻辑。
这种方法
实现了任何组件的通信,包括父子、兄弟、跨级,在Vue 1.X和Vue 2.X 都适用。如果深入使用,可以扩展bus实例,给它添加data、method、computed等选项,这些都是可以公用的,在业务中,尤其是协同开发时非常有用,因为需要共享一些通用的信息,比如用户登录的昵称、性别、邮箱等,还有用户的授权token等。只需在初始化时让bus获取一次,任何时间、任何组件就可以从中直接使用了,在单页面富应用(SPA)中国会很实用。