看這篇以前,若是沒有看過以前的文章,可拉到文章末尾查看以前的文章。vue
在標準瀏覽器中,咱們常用:addEventListener
來爲一個 DOM 添加一個事件(click
、mousemove
、tap
等)。node
在我看來,一個事件是一種行爲(或狀況),當發生這種行爲(或狀況)時,咱們要去作的事,好比今天下雨了,那我就得去找傘;鬧鐘響了,那我就得起牀等等。git
仔細看這些狀況,歸結到代碼中,無非就是一個行爲(或狀況)的名稱,和一些列的動做,而在 js
中動做就是 function
,一系列的動做就是一個函數的集合。github
如上所說,咱們把事件抽象成一個類數組
類下屬性 &
方法瀏覽器
ok 根據咱們的構想,在來看這個實現好的 Event
類app
let uid = 0 export class Event { constructor() { this.id = ++uid this._events = {} } $on(eventName, fn) { let ctx = this; // 若 _events 對象下無對應事件名,則新建一個數組,而後將處理函數推入數組 if(!ctx._events[eventName]){ ctx._events[eventName] = [] } ctx._events[eventName].push(fn) return ctx } $once(eventName, fn) { let ctx = this function on() { // 先取消,而後觸發,確保僅觸發一次 ctx.$off(eventName, on) fn.apply(ctx, arguments) } on.fn = fn ctx.$on(eventName, on) return object } $off(eventName) { let ctx = this const cbs = ctx._events[eventName] if (cbs) { // 取消置空便可 ctx._events[eventName] = null } return ctx } $emit(eventName, ...args) { let ctx = this let cbs = ctx._events[eventName] if (cbs) { cbs.forEach(func => func.apply(ctx, args)) } return ctx } }
一個簡單的事件管理的類便實現好了,讓咱們來測試一下:函數
import {Event} from "./Event"; let eventTest = new Event() eventTest.$on('testEvent', function (event) { console.log('測試事件添加,傳入參數爲' + event) }) eventTest.$emit('testEvent', '事件觸發成功') // 測試事件添加,傳入參數爲事件觸發成功 eventTest.$emit('testEvent', '事件再次觸發成功') // 測試事件添加,傳入參數爲事件再次觸發成功 eventTest.$off('testEvent') eventTest.$emit('testEvent', '事件取消,不會有輸出') // 無輸出 eventTest.$once('testOnce', function (event) { console.log('事件僅僅觸發一次,傳入參數爲' + event) }) eventTest.$emit('testOnce', '事件觸發成功') // 事件僅僅觸發一次,傳入參數爲事件觸發成功 eventTest.$emit('testOnce', '事件取消,不會有輸出') // 無輸出
ok 一個簡易的事件管理實現了,因爲這節內容與上幾節關係不大,因此這裏再次說下測試代碼的運行方式:測試
node
環境 8.11.1
往上,否則不可以支持 import
語法import
語法,文件後綴爲 .mjs
test.mjs
所在目錄命令行運行:node --experimental-modules test.mjs
便可點擊查看相關代碼優化