设计模式:发布订阅模式
$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
}
}