寫在前面
因為對Vue.js很感興趣,而且平時工作的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,并做了總結與輸出。
文章的原地址:https://github.com/answershuto/learnVue。
在學習過程中,為Vue加上了中文的注釋https://github.com/answershuto/learnVue/tree/master/vue-src,希望可以對其他想學習Vue源碼的小伙伴有所幫助。
可能會有理解存在偏差的地方,歡迎提issue指出,共同學習,共同進步。
Vue事件API
眾所周知,Vue.js為我們提供了四個事件API,分別是$on](https://cn.vuejs.org/v2/api/#vm-on-event-callback),[$once,$off](https://cn.vuejs.org/v2/api/#vm-off-event-callback),[$emit。
初始化事件
初始化事件在vm上創建一個_events對象,用來存放事件。_events的內容如下:
{ eventName: [func1, func2, func3]}存放事件名以及對應執行方法。
/*初始化事件*/export function initEvents (vm: Component) { /*在vm上創建一個_events對象,用來存放事件。*/ vm._events = Object.create(null) /*這個bool標志位來表明是否存在鉤子,而不需要通過哈希表的方法來查找是否有鉤子,這樣做可以減少不必要的開銷,優化性能。*/ vm._hasHookEvent = false // init parent attached events /*初始化父組件attach的事件*/ const listeners = vm.$options._parentListeners if (listeners) { updateComponentListeners(vm, listeners) }}$on
$on方法用來在vm實例上監聽一個自定義事件,該事件可用$emit觸發。
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component { const vm: Component = this /*如果是數組的時候,則遞歸$on,為每一個成員都綁定上方法*/ if (Array.isArray(event)) { for (let i = 0, l = event.length; i < l; i++) { this.$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 /*這里在注冊事件的時候標記bool值也就是個標志位來表明存在鉤子,而不需要通過哈希表的方法來查找是否有鉤子,這樣做可以減少不必要的開銷,優化性能。*/ if (hookRE.test(event)) { vm._hasHookEvent = true } } return vm }$once
$once監聽一個只能觸發一次的事件,在觸發以后會自動移除該事件。
Vue.prototype.$once = function (event: string, fn: Function): Component { const vm: Component = this function on () { /*在第一次執行的時候將該事件銷毀*/ vm.$off(event, on) /*執行注冊的方法*/ fn.apply(vm, arguments) } on.fn = fn vm.$on(event, on) return vm }$off
新聞熱點
疑難解答
圖片精選