Skip to content

Latest commit

 

History

History
668 lines (564 loc) · 15 KB

README.cn.md

File metadata and controls

668 lines (564 loc) · 15 KB

star Author

Version Downloads Size License TopLang issue test

🚀 功能强大、简单易用的事件库

Online Use | English | 更新日志 | 反馈错误/缺漏 | Gitee


1. 特性

  1. typescript 编写
  2. 多端支持
  3. 自定义事件顺序、多种触发模式
  4. 全局拦截机制
  5. 体积小巧,简单易用
  6. 支持创建模块,避免事件冲突

2. 快速使用

2.1 npm 安装

npm i tc-event
import event from 'tc-event';

event.regist('myEvent', (data) => {
    console.log('emited!', data);
})

event.emit('myEvent', 'Aha!');

2.2 cdn

<script src="https://cdn.jsdelivr.net/npm/tc-event/tc-event.min.js"></script>
<script>
    TEvent.regist('myEvent', function (data) {
        console.log('emited!', data);
    })

    TEvent.emit('myEvent', 'Aha!');
</script>

3 api

详情请参考 index.d.ts

export interface IEventEmitter {
    removed: boolean;
    interceptor: IEventInterceptor;
    name: string;
    getEventNames(): string[]; // 事件枚举
    getEvent(): IEventJson<CEvent>;
    getEvent(name: TEventName): CEvent;
    emit(name: TEventName, data?: any): boolean; // 触发事件
    onEmit(fn: IOnInterceptorEmit): void;
    regist: IRegistMethod;
    registObject(options: IEventRegistOption & {eventName: TEventName}): IListenerItem;
    onRegist(fn: IOnInterceptorRegist): void;
    checkEvent(name: TEventName): boolean; // 检查是否存在事件
    remove: IRemoveMethod;
    clear(name?: TEventName | TEventName[]): void;
    order(name: TEventName): number;
    registNotImmediate(name: TEventName, listener: IEventListener): IListenerItem;
    registNotImmediateOnce(name: TEventName, listener: IEventListener): IListenerItem;
    registOnce(name: TEventName, listener: IEventListener): IListenerItem;
    registSingle(name: TEventName, listener: IEventListener): IListenerItem;
}

export interface IEventStatic extends IEventEmitter {
    version: string;
    createModule (name: TModuleName): IEventEmitter;
    getModule (): IEventJson<IEventEmitter>;
    getModule (name: TModuleName): IEventEmitter;
    removeModule(name: TModuleName): void;
    clearModule(): void;
    EventEmitter: typeof EventEmitter;
}

4 使用实例

4.1 checkEvent

判断事件是否存在

const eventName = 'test-checkEvent';
const result = [];
result.push(event.checkEvent(eventName));
event.regist(eventName, () => {});
result.push(event.checkEvent(eventName));
event.emit(eventName);
result.push(event.checkEvent(eventName));
event.clear(eventName);
result.push(event.checkEvent(eventName));
event.regist(eventName, () => {});
result.push(event.checkEvent(eventName));
event.clear();
result.push(event.checkEvent(eventName));
console.log(result);
// [false, true, true, false, true, false]

4.2 clear 方法

清除单个或所有事件

const eventName = 'test-clear';
const result = [];
event.regist(eventName, () => {
    result.push(1);
});
event.emit(eventName);
event.clear(eventName);
event.emit(eventName);
event.regist(eventName, {
    immediate: false,
    listener: () => {
        result.push(2);
    }
});
event.emit(eventName);
event.clear();
event.emit(eventName);
console.log(result);
// [1, 2]

4.3 immediate 参数

immediate 参数表示注册事件时,如果该事件已经被触发过,是否需要立即触发当前的事件

默认值为 true

const eventName = 'test-immediate';
const result = [];
event.emit(eventName);

event.regist(eventName, () => {
    result.push(1);
});
event.regist(eventName, {
    immediate: true,
    listener () { result.push(2);}
});
event.regist(eventName, {
    immediate: false,
    listener () {result.push(3);}
});
console.log(result);
// [1, 2]

4.4 index 参数

index 参数表示注册事件时,希望插入的位置

const eventName = 'test-order';
    
const result = [];
event.regist(eventName, () => {
    result.push(1); // 1
});
event.regist(eventName, () => {
    result.push(2); // 1 2
});
event.regist(eventName, () => {
    result.push(3); // 1 2 3
});
event.regist(eventName, () => {
    result.push(4); // 1 2 3 4
});
event.regist(eventName, {
    index: 0,  // 5 1 2 3 4
    listener () {result.push(5);}
});
event.regist(eventName, {
    index: 2, // 5 1 6 2 3 4
    listener () {result.push(6);}
});
event.regist(eventName, {
    index: 1, // 5 7 1 6 2 3 4
    listener () {result.push(7);}
});
event.regist(eventName, {
    index: 100, // 5 7 1 6 2 3 4 8
    listener () {result.push(8);}
});
event.regist(eventName, {
    index: -3, // 9 5 7 1 6 2 3 4 8
    listener () {result.push(9);}
});
event.emit(eventName);
console.log(result);
// [9, 5, 7, 1, 6, 2, 3, 4, 8]

4.5 interceptor

全局拦截器,支持 onRegist 和 onEmit

const eventName1 = 'test-interceptor1';
const eventName2 = 'test-interceptor2';
const result = [];
event.onRegist(({name, item}) => {
    result.push(`onRegist: ${name}`);
});
event.onEmit(({name, item, data, firstEmit}) => {
    result.push(`onEmit: ${name} ${data} ${firstEmit}`);
});
event.regist(eventName1, () => {});
event.regist(eventName2, () => {});
event.emit(eventName1, `${eventName1} data`);
event.emit(eventName2, `${eventName2} data`);
event.emit(eventName2, `${eventName2} data2`);
console.log(result);
/*
    [
        'onRegist: test-interceptor1',
        'onRegist: test-interceptor2',
        'onEmit: test-interceptor1 test-interceptor1 data true',
        'onEmit: test-interceptor2 test-interceptor2 data true',
        'onEmit: test-interceptor2 test-interceptor2 data2 false'
    ]
*/

4.6 once 参数

once 参数 是否只触发依次

const eventName = 'test-once';
const result = [];

event.regist(eventName, () => {
    result.push(1);
});
event.regist(eventName, {
    once: true,
    listener () { result.push(2);}
});
event.regist(eventName, {
    once: false,
    listener () {result.push(3);}
});
event.emit(eventName);
event.emit(eventName);
console.log(result);
// [1, 2, 3, 1, 3]

4.7 times 参数

times 参数 监听触发的次数

const eventName = 'test-times';
const result = [];

event.regist(eventName, {
    times: 1,
    listener () { result.push(1);}
});
event.regist(eventName, {
    times: 2,
    listener () { result.push(2);}
});
event.regist(eventName, {
    times: 3,
    listener () { result.push(3);}
});
event.emit(eventName);
event.emit(eventName);
event.emit(eventName);
event.emit(eventName);
// [1, 2, 3, 2, 3, 3]

4.8 order 参数

控制插入事件的序号(和 index参数有区别)

const eventName = 'test-order';
            
const result = [];
event.regist(eventName, () => {
    result.push(1); // 1
});
event.regist(eventName, () => {
    result.push(2); // 1 2
});
event.regist(eventName, {
    order: 0, // 0 1 2
    listener () {result.push(3);}
});
event.regist(eventName, {
    order: 1, // 0 1 *1 2
    listener () {result.push(4);}
});
event.regist(eventName, {
    order: 1, // 0 1 *1 **1 2
    listener () {result.push(5);}
});
event.regist(eventName, {
    order: 1, // 0 ***1 1 *1 **1 2
    orderBefore: true,
    listener () {result.push(6);}
});
event.regist(eventName, {
    order: 10, // 0 ***1 1 *1 **1 2 10
    listener () {result.push(7);}
});
event.regist(eventName, () => { // 0 ***1 1 *1 **1 2 3 10
    result.push(8);
});
event.emit(eventName);
console.log(result);

4.9 single 参数

单例监听模式,对某个事件名启用 single 参数会覆盖之前该事件的所有监听函数

且之后该事件无需再带上 single 参数

启用single参数时, index order orderBefore 参数无效

const eventName = 'test-single';
const result = [];

event.regist(eventName, () => {
    result.push(1);
});
event.emit(eventName);
// 测试覆盖旧方法
event.regist(eventName, {
    single: true,
    immediate: false,
    listener: () => {
        result.push(2);
    }
});
event.emit(eventName);
event.clear(eventName);

event.regist(eventName, {
    single: true,
    listener () { result.push(3);}
});
event.regist(eventName, {
    single: true,
    listener () { result.push(4);}
});
event.emit(eventName);
// 测试single参数缓存
event.regist(eventName, {
    immediate: false,
    listener () { result.push(5);}
});
event.emit(eventName);
console.log(result);
// [1, 2, 4, 5]

4.10 name 参数

name 参数用来给一个监听增加一个参数

默认值为 eventName + id

const eventName = 'test-name';
    
const item1 = event.regist(eventName, () => {
});
const item2 = event.regist(eventName, {
    name: 'listener-name',
    listener () {}
});
// item1.name === 'test-name-1'
// item2.name === 'listener-name'

4.11 head 参数

head参数用于将监听添加到事件头部

const eventName = 'test-head';
const result = [];
event.regist(eventName, () => {
    result.push(1);
});
event.regist(eventName, {
    order: -1,
    listener () {result.push(2);}
});
event.regist(eventName, {
    index: -1,
    listener () {result.push(3);}
});
event.regist(eventName, {
    head: true,
    listener () {result.push(4);}
});
event.regist(eventName, {
    head: true,
    listener () {result.push(5);}
});
event.emit(eventName);
// result: [5, 4, 3, 2, 1]

4.12 tail 参数

tail参数用于将监听添加到事件尾部

const eventName = 'test-tail';
const result = [];
event.regist(eventName, () => {
    result.push(1);
});
event.regist(eventName, {
    order: 100,
    listener () {result.push(2);}
});
event.regist(eventName, {
    index: 100,
    listener () {result.push(3);}
});
event.regist(eventName, {
    listener () {result.push(4);}
});
event.regist(eventName, {
    tail: true,
    listener () {result.push(5);}
});
event.regist(eventName, {
    tail: true,
    listener () {result.push(6);}
});
event.emit(eventName);
// result: [1, 4, 2, 3, 5, 6]

4.13 order 函数

获取某个监听的序号

const eventName = 'test-order-fn';
const result = [];

event.regist(eventName, () => {
    result.push(1);
});
event.regist(eventName, () => {
    result.push(2);
});
const e1 = event.regist(eventName, () => {
    result.push(3);
});
const e2 = event.regist(eventName, {
    order: 1,
    listener () { result.push(4);}
});
event.regist(eventName, () => {
    result.push(5);
});
event.emit(eventName);
console.log([result, event.order(eventName), e1.order, e2.order]);
// [[1, 4, 2, 3, 5], 4, 3, 1

4.14 remove 函数

移除事件监听

const eventName = 'test-remove';
const result = [];
const l4 = () => { result.push(4); };
const l5 = () => { result.push(5); };
const l6 = () => { result.push(6); };
const l7 = () => { result.push(7); };
event.regist(eventName, () => {
    result.push(1);
});
event.regist(eventName, () => {
    result.push(2);
});
event.regist(eventName, () => {
    result.push(3);
    event.remove(eventName, l4, true);
    event.remove(eventName, l5);
    event.regist(eventName, l7);
});
event.regist(eventName, l4);
event.regist(eventName, l5);
event.regist(eventName, l6);
event.remove(eventName, l6);
event.emit(eventName);
event.emit(eventName);
console.log(result);
// [1, 2, 3, 7, 5, 1, 2, 3, 7, 7]

4.15 registNotImmediate

event.registNotImmediate('xxx', ()=>{})
// 等价于
event.regist('xxx', {
    immediate: false,
    listener: ()=>{}
})

4.16 registOnce

event.registOnce('xxx', ()=>{})
// 等价于
event.regist('xxx', {
    once: true,
    listener: ()=>{}
})

4.17 registNotImmediateOnce

event.registNotImmediateOnce('xxx', ()=>{})
// 等价于
event.regist('xxx', {
    immediate: false,
    once: true,
    listener: ()=>{}
})

4.18 registSingle

event.registSingle('xxx', ()=>{})
// 等价于
event.regist('xxx', {
    single: true,
    listener: ()=>{}
})

4.19 监听回调参数

监听函数第二个参数是一个json,包含有三个属性

  1. firstEmit 表示该监听是否是首次触发
  2. remove 是移除当前监听的方法
  3. clear 是移除当前事件的方法
  4. item 是当前的监听对象
event.regist('xxx', (data, {firstEmit, item, remove, clear})=>{

})

4.20 链式调用

regist函数当指传入事件名时会启用链式调用

所有参数都可通过链式调用,所有api都是可选的,最后需要通过 listen 方法触发监听

event.regist('xxx')
    .index(1)
    .order(1)
    .orderBefore()
    .notImmediate()
    .single()
    .once()
    .times(1)
    .listener()
    .name('xxx')
    .head()
    .tail()
    .listen();

声明文件如下

interface IEventLink {
    single: (single: boolean) => IEventLink;
    notImmediate: (immediate: boolean) => IEventLink;
    once: (once: boolean) => IEventLink;
    index: (index: number) => IEventLink;
    order: (order: number) => IEventLink;
    orderBefore: (orderBefore: boolean) => IEventLink;
    listener: (listener: IEventListener) => IEventLink;
    name: (name: string) => IEventLink;
    head: () => IEventLink;
    tail: ()=> IEventLink;
    times: (times: number)=> IEventLink;
    listen: (listener?: IEventListener) => IListenerItem;
}

4.21 事件模块

  1. createModule
const result = [];
const name = 'module_event';
const moduleA = event.createModule('A');
const moduleB = event.createModule('B');

moduleA.regist(name, data => {result.push('A' + data);});
moduleB.regist(name, data => {result.push('B' + data);});

moduleA.emit(name, 1);
moduleA.emit(name, 2);
console.log(result);
  1. getModule
event.createModule('A');
event.createModule('B');

console.log([
    event.getModule('A').moduleName,
    event.getModule('B').moduleName,
]);