Skip to content
vue的一个小插件,用于单页应用下页面之间的消息传递。利用事件的命名空间,每个组件只需关心在event-bus上要订阅哪些消息,组件销毁时自身添加在event-bus的消息handler会自动清理掉,不影响其它组件。
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
demo
dist
src
.babelrc
.gitignore
.npmignore
README.md
package.json
rollup.config.js
server.js

README.md

npm npm npm

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上用自己的命名空间注册的事件监听,保证不影响其它实例。

用法

安装:

npm install vue-breif-event-bus

引用:

  • webpack等构建环境:

    import 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:

    <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使用

    import 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,那么可以利用下面的方式来处理:

    import 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

git clone https://github.com/liuyunzhuge/vue-event-bus
cd vue-event-bus
npm install
node server

打开http://localhost:8080/demo/01.htmlhttp://localhost:8080/demo/02.html即可预览前面两种使用方式的实际效果。这两个demo都是基于keep-alivecomponent组件写的,keep-alive配置了有max属性,所以能够模拟出vue实例被自动销毁的场景,从而测试$eventBus是否会自动移除掉被销毁实例的监听;同时有的组件用了$once的api,所以相应的回调只会派发一次;最后一个组件有用$emit的api,所以通过它能给其它被keep-alive缓存的组件,派发消息。

其它

给Vue实例创建独一无二的命名空间,使用的算法是:

function _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)
    })
}

可以通过下面的方式来定义新的创建方式:

Vue.use(EventBus, {
    createNamespace(instance) {
        // new implementation
    }
})

补充:这个库适合与类似vue-navigation这种基于路由模拟APP页面栈的工具库一起使用。

polyfills

如果你在vue项目中,使用vue-breif-event-bus,你可能需要添加以下这些polyfills(参考vue-cli官方polyfills说明):

'es.symbol',
'es.symbol.description',
'es.symbol.iterator',
'es.array.concat',
'es.array.iterator',
'es.array.join',
'es.array.slice',
'es.array.sort',
'es.array.splice',
'es.date.to-string',
'es.function.name',
'es.map',
'es.object.define-property',
'es.object.to-string',
'es.regexp.constructor',
'es.regexp.exec',
'es.regexp.to-string',
'es.string.iterator',
'es.string.split',
'web.dom-collections.iterator',
'es.array.map',
'es.object.get-own-property-descriptor',
'es.string.replace'

以上polyfills是根据vue-breif-event-busbreif-event-bus的源码,基于以下的browserlist配置:

'Android >= 4',
'iOS >= 8'

利用@babel/preset-envuseBuiltIns: "usage"特性检测出来的。如果你想要polyfill的targets不一样,可以自行用babel来检测需要polyfill的features。

You can’t perform that action at this time.