众所周知,
$on
是作事件监听,$emit
是作事件的派发,但对于$dispatch
和$broadcast
你们可能就比较陌生了,这对api是vue1.x版本的,在vue2.x里已经被废弃vue
$on
和$emit
$dispatch
与 $broadcast
$dispatch
:用于向上级派发事件,只要是它的父级(一级或多级以上),均可以在组件内经过$on
监听到$broadcast
: 用于向下级派发事件,只要是它的子组件,均可以在组件内经过$on
监听到如何经过
$on
和$emit
来实现$dispatch
和$broadcast
,思路大概是,向上递归查找要通讯的组件,或者向下,咱们将该功能代码提到mixin中,方便各组件复用api
// emitter.js const broadcast = function(comName,event,data) { this.$children.forEach(p =>{ if(p.$options.name === comName) { p.$emit(event, data) } else{ broadcast.apply(p,comName,event,data) } }) } methods: { /** * comName 目标组件 * event 事件名 * data 要传的数据 */ broadcast(comName,event,data) { broadcast.call(this, arguments) }, dispatch (comName,event,data) { let parent = this.$parent || this.$root; let name = parent.$options.name; // 这里是找最接近的父组件 while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.name; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, }
使用案例app
// 父组件A,省略部分代码 <template> <button @click="handleClick">触发事件</button> </template> <script> import Emitter from '../mixins/emitter.js'; export default { name: 'componentA', mixins: [ Emitter ], methods: { handleClick () { this.broadcast('componentB', 'sendMsg', 'Hello 我是父组件A'); } } } </script> // 子组件B,省略部分代码 <script> import Emitter from '../mixins/emitter.js'; export default { name: 'componentB', mixins: [ Emitter ], // 在created或者mounted作事件监听 created () { this.$on('sendMsg', this.showMsg) }, methods: { showMsg (data) { alert(data) } } } </script>