实现 VUE 中 MVVM - step7 - Event

栏目: 编程工具 · 发布时间: 5年前

内容简介:在标准浏览器中,我们经常使用:在我看来,一个事件是一种行为(或情况),当发生这种行为(或情况)时,我们要去做的事,比如今天下雨了,那我就得去找伞;闹钟响了,那我就得起床等等。仔细看这些情况,归结到代码中,无非就是一个行为(或情况)的名称,和一些列的动作,而在

在标准浏览器中,我们经常使用: addEventListener 来为一个 DOM 添加一个事件( clickmousemovetap 等)。

在我看来,一个事件是一种行为(或情况),当发生这种行为(或情况)时,我们要去做的事,比如今天下雨了,那我就得去找伞;闹钟响了,那我就得起床等等。

仔细看这些情况,归结到代码中,无非就是一个行为(或情况)的名称,和一些列的动作,而在 js 中动作就是 function ,一系列的动作就是一个函数的集合。

实现

如上所说,我们把事件抽象成一个类

类下属性 & 方法

  • _events 一个对象 {key: eventName, value: Array<Function,Function...>}
  • $on(eventName, func) 添加具体事件的处理函数
  • $off(eventName) 取消事件处理函数
  • $emit(eventName, data1, data2, ...) 用于触发事件
  • $once(eventName, func) 设置仅触发一次的事件

ok 根据我们的构想,在来看这个实现好的 Event

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 一个简易的事件管理实现了,由于这节内容与上几节关系不大,所以这里再次说下测试代码的运行方式:

  1. node 环境 8.11.1 往上,不然不能够支持 import 语法
  2. 为了不转码支持 import 语法,文件后缀为 .mjs
  3. 进入到 test.mjs 所在目录命令行运行: node --experimental-modules test.mjs 即可

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective C++

Effective C++

梅耶 (Scott Meyers) / 侯捷 / 电子工业出版社 / 2011-1-1 / 65.00元

《Effective C++:改善程序与设计的55个具体做法(第3版)(中文版)(双色)》内容简介:有人说C++程序员可以分为两类,读过Effective C++的和没读过的。世界项级C++大师scott Meyers成名之作的第三版的确当得起这样的评价。当您读过《Effective C++:改善程序与设计的55个具体做法(第3版)(中文版)(双色)》之后,就获得了迅速提升自己C++功力的一个契机......一起来看看 《Effective C++》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具