看这篇以前,若是没有看过以前的文章,可拉到文章末尾查看以前的文章。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
便可点击查看相关代码优化