实现 VUE 中 MVVM - step7 - Event

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

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

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

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

仔细看这些情况,归结到代码中,无非就是一个行为(或情况)的名称,和一些列的动作,而在 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 即可

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

查看所有标签

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

NoSQL精粹

NoSQL精粹

[美]Pramod J. Sadalage、[美]Martin Fowler / 爱飞翔 / 机械工业出版社 / 2013-8 / 49.00元

《NoSQL精粹》为考虑是否可以使用和如何使用NoSQL数据库的企业提供了可靠的决策依据。它由世界级软件开发大师和软件开发“教父”Martin Fowler与Jolt生产效率大奖图书作者Pramod J. Sadalage共同撰写。书中全方位比较了关系型数据库与NoSQL数据库的异同;分别以Riak、MongoDB、Cassandra和Neo4J为代表,详细讲解了键值数据库、文档数据库、列族数据库......一起来看看 《NoSQL精粹》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

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

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具