Source: eventbus.js

/**
 * 事件总线类
 * 
 * @example
 * 
 * var ev = new eventbus()
 * 
 * // 绑定事件
 * ev.on('test',()=>{
 *  console.log('执行测试方法')
 * })
 * ev.emit('test') // 触发事件
 * ev.off('test') // 取消事件
 * 
 * 
 */
class eventbus {
    // 事件侦听器
    _listener = {}
    // 默认忽略事件名称大小写
    _ignoreCase = true
    /**
     * 监听当前实例上的自定义事件。事件可以由 emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
     * @param {String} event 事件名称
     * @param {Function} fn 回调函数
     * @returns {eventbus} 返回当前事件对象
     */
    on(event, fn) {
        if (typeof event === "string" && typeof fn === "function") {
            event = this._ignoreCase ? event.toLowerCase() : event
            if (this._listener[event]) {
                this._listener[event].push(fn);
            } else {
                this._listener[event] = [fn];
            }
        }
        return this;
    }
    /**
     * 监听一个自定义事件,但是只触发一次。一旦触发之后,监听器就会被移除。
     * @param {String} event 事件名称
     * @param {Function} fn 回调函数
     * @returns {eventbus} 返回当前事件对象
     */
    once(event, fn) {
        if (typeof event === "string" && typeof fn === "function") {
            event = this._ignoreCase ? event.toLowerCase() : event
            var wrapper = function (event, fn) {
                return function (...args) {
                    fn.apply(this, args)
                    this.off(event, wrapper)
                }
            }(event, fn)
            this.on(event, wrapper)
        }
        return this;
    }
    /**
     * 移除自定义事件监听器。
     *
     * 如果没有提供参数,则移除所有的事件监听器;
     *
     * 如果只提供了事件,则移除该事件所有的监听器;
     *
     * 如果同时提供了事件与回调,则只移除这个回调的监听器
     * @param {String} event 事件名称
     * @param {Function} fn 回调函数
     * @returns {EventTarget} 返回当前事件对象
     */
    off(event, fn) {
        if (typeof event === "string" && typeof fn === "function") {
            event = this._ignoreCase ? event.toLowerCase() : event
            var key = event
            // 如果同时提供了事件与回调,则只移除这个回调的监听器
            this._listener[key] = this._listener[key] && this._listener[key].filter(f => f !== fn)
        } else if (typeof fn === "function") {
            // 如果只提供了事件,则移除该事件所有的监听器;
            for (var key in this._listener) {
                this._listener[key] = this._listener[key] && this._listener[key].filter(f => f !== fn)
            }
        } else {
            // 如果没有提供参数,则移除所有的事件监听器;
            this._listener = {}
        }
        return this;
    }
    /**
     * 触发当前实例上的事件。附加参数都会传给监听器回调。
     * @param {String} eventName 事件名称
     * @param {Array} args 参数
     * @returns {eventbus} 返回当前事件对象
     */
    emit(eventName) {
        if (eventName && this._listener[eventName]) {
            eventName = this._ignoreCase ? eventName.toLowerCase() : eventName
            var length = this._listener[eventName].length
            for (var start = 0; start < length; start++) {
                var fn = this._listener[eventName][start];
                if (fn !== null && fn !== undefined)
                    fn.apply(this, [...arguments].slice(1));
            }
        }
        return this;
    }
}

export default eventbus