VUE - MVVM - part8 - 優化Event

看這篇以前,若是沒有看過以前的文章,可拉到文章末尾查看以前的文章。vue

回顧

在上一步咱們實現了一個簡易的事件管理的類,接下來咱們把它給優化下,方便咱們的使用。主要優化內容:git

  1. 方便爲多個事件添加同一個函數
  2. 方便爲一個事件添加多個函數
  3. 有針對性的取消事件的函數

第一點和第二點都要修改 $on 函數,因此咱們一塊兒改:github

以前的代碼數組

$on(eventName, fn) {
    let ctx = this;
    if(!ctx._events[eventName]){
        ctx._events[eventName] = []
    }
    ctx._events[eventName].push(fn)
    return ctx
}

優化以後的代碼函數

$on(eventName, fn) {
    let ctx = this
    // 處理事件名是數組的狀況
    if (Array.isArray(eventName)) {
        // 遞歸調用 $on 函數
        eventName.forEach(name => this.$on(name, fn))
    } else {
        // 處理處理函數爲數組的狀況
        // 將處理函數統一成數組方便添加
        if (!Array.isArray(fn)) {
            fn = [fn]
        }
        if(!ctx._events[eventName]){
            ctx._events[eventName] = []
        }
        ctx._events[eventName].push(fn)
    }
    return ctx
}

很簡單的優化,但卻讓 $on 函數更加方便的使用。測試

接着咱們來優化 $off 。咱們先看看以前的代碼:優化

$off(eventName) {
    let ctx = this
    const cbs = ctx._events[eventName]
    if (cbs) {
        // 取消置空便可
        ctx._events[eventName] = null
    }
    return ctx
}

咱們只作了清空特定事件,其實咱們能作的還有不少,this

  1. 清空全部事件
  2. 清空多個事件
  3. 取消特定事件的特定處理函數

優化的細節看代碼中的註釋code

$off(eventName, fn) {
    let ctx = this
    // 清空全部事件
    if (!arguments.length) {
        ctx._events = Object.create(null)
        return ctx
    }
    // 清空多個事件
    if (Array.isArray(eventName)) {
        eventName.forEach(name => this.$off(name, fn))
        return ctx
    }
    // 若沒有事件對應的函數列表則不用處理
    const cbs = ctx._events[eventName]
    if (!cbs) {
        return ctx
    }
    // 清空特定事件
    if (!fn) {
        ctx._events[eventName] = null
        return ctx
    }
    // 取消特定事件的特定處理函數
    if (fn) {
        let cb
        let i = cbs.length
        // 處理一次取消多個的狀況
        if (Array.isArray(fn)) {
            fn.forEach(fnc => this.$off(eventName, fnc))
        }
        while (i--) {
            cb = cbs[i]
            if (cb === fn || cb.fn === fn) {
                cbs.splice(i, 1)
                break
            }
        }
    }
    return ctx
}

ok 優化好了,測試一下:對象

import {Event} from "./Event";

let eventTest = new Event()

eventTest.$on('eventName1', (e) => {
    console.log('一次添加一個處理函數')
    console.log(e)
})

eventTest.$on('eventName2', [(e) => {
    console.log('一次添加多個處理函數,第一個')
    console.log(e)
}, (e) => {
    console.log('一次添加多個處理函數,第二個')
    console.log(e)
}])

eventTest.$on(['eventName3', 'eventName4'], (e) => {
    console.log('多個事件添加同一處理函數')
    console.log(e)
})

eventTest.$on(['eventName5', 'eventName6'], [(e) => {
    console.log('多個事件添加多個處理函數,第一個')
    console.log(e)
}, (e) => {
    console.log('多個事件添加多個處理函數,第二個')
    console.log(e)
}])

eventTest.$emit('eventName1', '傳入參數1')
// 一次添加一個處理函數
// 傳入參數1
eventTest.$emit('eventName2', '傳入參數2')
// 一次添加多個處理函數,第一個
// 傳入參數2
// 一次添加多個處理函數,第二個
// 傳入參數2
eventTest.$emit('eventName3', '傳入參數3')
// 多個事件添加同一處理函數
// 傳入參數3
eventTest.$emit('eventName4', '傳入參數4')
// 多個事件添加同一處理函數
// 傳入參數4
eventTest.$emit('eventName5', '傳入參數5')
// 多個事件添加多個處理函數,第一個
// 傳入參數5
// 多個事件添加多個處理函數,第二個
// 傳入參數5
eventTest.$emit('eventName6', '傳入參數6')
// 多個事件添加多個處理函數,第一個
// 傳入參數6
// 多個事件添加多個處理函數,第二個
// 傳入參數6
console.log('------------------------------')

eventTest.$off('eventName1')
eventTest.$off(['eventName2', 'eventName3'])

eventTest.$emit('eventName1', '傳入參數1')
// 無輸出
eventTest.$emit('eventName2', '傳入參數2')
// 無輸出
eventTest.$emit('eventName3', '傳入參數3')
// 無輸出
eventTest.$emit('eventName4', '傳入參數4')
// 多個事件添加同一處理函數
// 傳入參數4
eventTest.$emit('eventName5', '傳入參數5')
// 多個事件添加多個處理函數,第一個
// 傳入參數5
// 多個事件添加多個處理函數,第二個
// 傳入參數5
eventTest.$emit('eventName6', '傳入參數6')
// 多個事件添加多個處理函數,第一個
// 傳入參數6
// 多個事件添加多個處理函數,第二個
// 傳入參數6
console.log('------------------------------')

eventTest.$off()
eventTest.$emit('eventName1', '傳入參數1')
// 無輸出
eventTest.$emit('eventName2', '傳入參數2')
// 無輸出
eventTest.$emit('eventName3', '傳入參數3')
// 無輸出
eventTest.$emit('eventName4', '傳入參數4')
// 無輸出
eventTest.$emit('eventName5', '傳入參數5')
// 無輸出
eventTest.$emit('eventName6', '傳入參數6')
// 無輸出
console.log('------------------------------')

這兩節吧,事件介紹了下,一個健壯的事件的類也編寫好了,接下來咱們把這 8 步實現的內容集合到一個對象下,也就是 Vue 下,敬請期待。

點擊查看相關代碼

系列文章地址

  1. VUE - MVVM - part1 - defineProperty
  2. VUE - MVVM - part2 - Dep
  3. VUE - MVVM - part3 - Watcher
  4. VUE - MVVM - part4 - 優化Watcher
  5. VUE - MVVM - part5 - Observe
  6. VUE - MVVM - part6 - Array
  7. VUE - MVVM - part7 - Event
  8. VUE - MVVM - part8 - 優化Event
  9. VUE - MVVM - part9 - Vue
  10. VUE - MVVM - part10 - Computed
  11. VUE - MVVM - part11 - Extend
  12. VUE - MVVM - part12 - props
  13. VUE - MVVM - part13 - inject & 總結
相關文章
相關標籤/搜索