项目地址:vue-event-bus
vue-event-bus
是最近开发的一个vue小插件,用于单页应用下页面之间的消息传递。利用事件的命名空间,每个组件只需关心在event-bus上要订阅哪些消息,组件销毁时自身添加在event-bus的消息handler会自动清理掉,同时不影响其它组件。
这是基于event-bus开发出来的,event-bus
提供了带命名空间的事件派发管理,所以如果要把event-bus
用于Vue中的话,仅需要考虑给每个组件实例都生成一个独一无二的事件命名空间,然后在使用on off trigger once
这些api的时候,自动加上Vue实例的命名空间即可;另外借助hook:beforeDestroy
这个生命周期钩子,还能在Vue组件实例销毁前,自动移除掉自己在event-bus
上用自己的命名空间注册的事件监听,保证不影响其它实例。
用法
安装:
1 | npm install vue-breif-event-bus |
引用:
webpack等构建环境:
1
2
3
4
5
6import Vue from 'vue'
import EventBus from 'vue-breif-event-bus'
Vue.use(EventBus)
// start your code浏览器环境
通过
npm install vue-breif-event-bus
安装最新版,到本地node_modules/vue-breif-event-bus
,直接引用dist/index.umd.min.js
文件即可。eg:1
2
3
4
5
6
7
8<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-breif-event-bus/dist/index.umd.js"></script>
<script>
Vue.use(EventBus)
// start your code
</script>
使用
基于Vue.prototype使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import Vue from 'vue'
import EventBus from 'vue-breif-event-bus'
Vue.use(EventBus)
let some = new Vue({
template: `<div>template</div>`,
created(){
this.$eventBus.$on('event-name', ()=> {
// handler
})
this.$eventBus.$once('event-name', ()=> {
// once handler
})
this.$eventBus.$off('event-name', ()=> {
// remove handler
})
this.$eventBus.$emit('event-name', {
desc: 'any data'
})
}
})vue-breif-event-bus
作为插件,在Vue的prototype
上注册了一个$eventBus
的属性,所以任何Vue实例都可以直接通过this.$eventBus
访问到一个基于event-bus构造的具备命名空间事件管理的对象(不是event-bus
的实例),在vue-breif-event-bus
内部,为了让使用者更加习惯地使用Vue api一致的事件管理方式,重新给$eventBus
设计了四个api,分别是$on $once $off $emit
,用法与Vue官方api一致。noConflict
如果不想污染
Vue.prototype
,那么可以利用下面的方式来处理:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34import Vue from 'vue'
import EventBus from 'vue-breif-event-bus'
Vue.use(EventBus)
let EventBusManager = Vue.prototype.$eventBus.noConflict()
// Vue.prototype.$eventBus will be set to previous value
Vue.mixin({
computed: {
$eventBus() {
return EventBusManager(this)
}
}
})
let some = new Vue({
template: `<div>template</div>`,
created(){
this.$eventBus.$on('event-name', ()=> {
// handler
})
this.$eventBus.$once('event-name', ()=> {
// once handler
})
this.$eventBus.$off('event-name', ()=> {
// remove handler
})
this.$eventBus.$emit('event-name', {
desc: 'any data'
})
}
})
DEMO
1 | git clone https://github.com/liuyunzhuge/vue-event-bus |
打开http://localhost:8080/demo/01.html
和http://localhost:8080/demo/02.html
即可预览前面两种使用方式的实际效果。这两个demo都是基于keep-alive
和component
组件写的,keep-alive
配置了有max
属性,所以能够模拟出vue实例被自动销毁的场景,从而测试$eventBus
是否会自动移除掉被销毁实例的监听;同时有的组件用了$once
的api,所以相应的回调只会派发一次;最后一个组件有用$emit
的api,所以通过它能给其它被keep-alive
缓存的组件,派发消息。
其它
给Vue实例创建独一无二的命名空间,使用的算法是:1
2
3
4
5
6
7
8function _createNamespace(instance) {
const t = 'xxxxyyyyxy'
return '.' + t.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0
const v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
可以通过下面的方式来定义新的创建方式:1
2
3
4
5Vue.use(EventBus, {
createNamespace(instance) {
// new implementation
}
})
补充:这个库适合与类似vue-navigation这种基于路由模拟APP页面栈的工具库一起使用。