Vue.prototype.$on = function (event, fn) { const hookRE = /^hook:/ //檢測自定義事件名是不是hook:開頭 const vm = this if (Array.isArray(event)) { // 若是第一個參數是數組 for (let i = 0; i < event.length; i++) { this.$on(event[i], fn) // 遞歸 } } else { (vm._events[event] || (vm._events[event] = [])).push(fn) // 若是有對應事件名就push,沒有建立爲空數組而後push if (hookRE.test(event)) { // 若是是hook:開頭 vm._hasHookEvent = true // 標誌位爲true } } return vm }
Vue.prototype.$emit = function (event) { const vm = this let cbs = vm._events[event] // 找到事件名對應的回調集合 if (cbs) { const args = toArray(arguments, 1) // 將附加參數轉爲數組 for (let i = 0; i < cbs.length; i++) { cbs[i].apply(vm, args) // 挨個執行對應的回調集合 } } return vm }
在組件(當前組件實例)的$on和$emit的執行原理:數組
$on往當前組件實例的事件中心(this._events)添加自定義事件
$emit在事件中心找到對應的自定義事件後調用事件app
父子組件經過@傳遞事件詳解:this
父組件在編譯模板後將子組件(@自定義事件="回調")的自定義事件及其回調經過$on添加到子組件的事件中心(this._events)spa