bus作为一个简单的组件传递事件,用于解决跨级和兄弟组件通信的问题。
vue-bus 插件像vue-router和Vuex一样,给Vue添加一个属性$bus,并代理
e
m
i
t
、
emit、
emit、on、$off三个方法。
vue-bus.js
const install = function (Vue) {
const Bus = new Vue({
methods: {
emit (event, ...args) {
this.$emit(event, ...args);
},
on (event, callback) {
this.$on(event, callback)
},
off (event, callback) {
this.$off(event, callback);
}
}
});
Vue.prototype.$bus = Bus;
};
export default install;
语法提示:
emit(event, ...args)
中的…args 是函数参数的解构,因为不知道组件会传递多少个参数,使用…args 可以把从当前参数(这里是第二个)到最后的参数都获取到。
Counter.vue组件
<template>
<div>
{{ number }}
<button @click="handleAddRandom">随机增加</button>
</div>
</template>
<script>
export default {
props: {
number: {
type: Number
}
},
methods: {
handleAddRandom () {
const num = Math.floor(Math.random () * 100 +1);
this.$bus.emit('add', num)
}
}
};
</script>
<style scoped></style>
main.js使用插件
import VueBus from './pages/VueBus/vue-bus';
Vue.use(VueBus);
在index.vue使用Counter组件
<template>
<div>
随机增加:
<Counter :number="number"></Counter>
</div>
</template>
<script>
import Counter from '../pages/vueBus/Counter'
export default {
components: {
Counter
},
created () {
this.$bus.on('add', num => {
this.number += num;
})
},
};
使用以上方式解决了跨组件通信的问题,而且通过插件的形式使用后,所有的组件都可以直接用 $bus,无需每个组件都导入bus组件。
注意
1、$bus.on 应该在 created 钩子内使用,如果在 mounted 使用,他可能接收不到其他组件来自 created 钩子内发出的事件;
2、使用了 b u s . o n , 在 b e f o r e D e s t o r y 狗 子 里 应 该 使 用 bus.on,在beforeDestory狗子里应该使用 bus.on,在beforeDestory狗子里应该使用bus.off解除,因为组件销毁后,没必要把监听的句柄存在vue-bus里了,所以index.vue中应该再加入
beforeDestory () {
this.$bus.off('add', this.handleAddRandom)
}