设计模式:发布订阅模式
$on订阅,实例vm._events[事件名称]收集回调组
$emit发布,访问vm._events[事件名称],遍历执行回调组
具体实现:
$on(eventname,cbs)
//如果没有此事件先执行vm. _events.[eventname]=[],再push
vm. _events[eventname]. push(cb)
vm.$emit(eventname,…args)
eventname先被转小写,且检测命名是否合法
然后在vm. _events中查询有没此事件
vm. _events[eventname]获取回调组,执行所有回调, args作为回调传入的参数
代码实现:
var hookRE = /^hook:/; Vue.prototype.$on = function (event, fn) { var vm = this; if (Array.isArray(event)) { for (var i = 0, l = event.length; i < l; i++) { vm.$on(event[i], fn); } } else { (vm._events[event] || (vm._events[event] = [])).push(fn); // optimize hook:event cost by using a boolean flag marked at registration // instead of a hash lookup if (hookRE.test(event)) { vm._hasHookEvent = true; } } return vm };
Vue.prototype.$emit = function (event: string): Component { const vm: Component = this let cbs = vm._events[event] if (cbs) { cbs = cbs.length > 1 ? toArray(cbs) : cbs const args = toArray(arguments, 1) for (let i = 0, l = cbs.length; i < l; i++) { try { cbs[i].apply(vm, args) } catch (e) { handleError(e, vm, `event handler for "${event}"`) } } } return vm } }