當前位置:
首頁 > 知識 > Vue事件機制

Vue事件機制

Vue事件機制

Vue事件API

眾所周知,Vue.js為我們提供了四個事件API,分別是$on,$once,$off,$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

$off用來移除自定義事件

Vue.prototype.$off = function (event?: string | Array<string>, fn?: Function): Component {

const vm: Component = this

// all

/*如果不傳參數則註銷所有事件*/

if (!arguments.length) {

vm._events = Object.create(null)

return vm

}

// array of events

/*如果event是數組則遞歸註銷事件*/

if (Array.isArray(event)) {

for (let i = 0, l = event.length; i < l; i++) {

this.$off(event[i], fn)

}

return vm

}

// specific event

const cbs = vm._events[event]

/*Github:https://github.com/answershuto*/

/*本身不存在該事件則直接返回*/

if (!cbs) {

return vm

}

/*如果只傳了event參數則註銷該event方法下的所有方法*/

if (arguments.length === 1) {

vm._events[event] = null

return vm

}

// specific handler

/*遍歷尋找對應方法並刪除*/

let cb

let i = cbs.length

while (i--) {

cb = cbs[i]

if (cb === fn || cb.fn === fn) {

cbs.splice(i, 1)

break

}

}

return vm

}

$emit

$emit用來觸髮指定的自定義事件。

Vue.prototype.$emit = function (event: string): Component {

const vm: Component = this

if (process.env.NODE_ENV !== "production") {

const lowerCaseEvent = event.toLowerCase()

if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {

tip(

`Event "${lowerCaseEvent}" is emitted in component ` +

`${formatComponentName(vm)} but the handler is registered for "${event}". ` +

`Note that HTML attributes are case-insensitive and you cannot use ` +

`v-on to listen to camelCase events when using in-DOM templates. ` +

`You should probably use "${hyphenate(event)}" instead of "${event}".`

)

}

}

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++) {

cbs[i].apply(vm, args)

}

}

return vm

}

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 PHP愛好者 的精彩文章:

數字證書的作用和原理概述
CentOS 配置 nginx 範例
Postfix 安裝SSL證書
Lighttpd SSL安裝文檔
ProFTPD 安裝SSL證書

TAG:PHP愛好者 |