0.0.4 • Published 2 years ago

custom-app-event v0.0.4

Weekly downloads
-
License
ISC
Repository
-
Last release
2 years ago

Event 库,快速实现发布订阅模式

参数

// 事件名: 通知的值的类型
interface EventName {
  addEvent: number;
}

/**
 * 初始化支持传入参数, 传入一个interface,
 * @param debug 是否打印日志,默认false
 * @param tagLen 生成tag长度,默认6
 */
new AppEvent<EventName>({ debug: true, tagLen: 8 });

// 添加订阅的时候,第三个参数支持传入一个指定tag
// 返回值为一个tag
const tag = appEvent.addListen('addEvent', (value) => {}, 'testTag');

// 发布订阅的时候,支持传入tag和value,
// addEvent: number => 表示value的类型是number
// 如果不传入tag, 则通知addEvent事件的所有订阅者
appEvent.notification('addEvent', {
  tag: 'testTag',
  value: 100,
});

// 移除订阅的时候,支持传入第二个参数tag
// 如果不指定tag,则移除addEvent事件的所有订阅者
appEvent.removeListen('addEvent', 'testPage');

基本使用 demo

import { AppEvent } from 'app-event';

// 事件名: 通知的值的类型
interface EventName {
  addEvent: number;
}

let index = 0;

const appEvent = new AppEvent<EventName>({ debug: true });

// 添加订阅
appEvent.addListen('addEvent', (value) => {
  index++;
  console.log(`value: ${value}`);
  if (value === 10) {
    // 移除订阅
    appEvent.removeListen('addEvent');
  }
});

// 发布订阅
setInterval(() => {
  appEvent.notification('addEvent', {
    value: index,
  });
}, 1000);

使用 tag 控制更加细小粒度发布,订阅,通知

// 添加订阅
const tag1 = appEvent.addListen('addEvent', (value) => {
  index++;
  if (value === 10) {
    // 通过指定tag来移除对应的订阅
    appEvent.removeListen('addEvent', tag1);
  }
  console.log(`value: ${value}`);
});

// 添加订阅
const tag2 = appEvent.addListen('addEvent', (value) => {
  index++;
  console.log(`value: ${value}`);
  if (value === 20) {
    // 通过指定tag来移除对应的订阅
    appEvent.removeListen('addEvent', tag2);
  }
});

// 发布订阅
setInterval(() => {
  // 通过tag来发布对应tag对应订阅
  appEvent.notification('addEvent', {
    value: index,
    tag: tag1,
  });
}, 500);

// 发布订阅
setInterval(() => {
  // 通过tag来发布对应tag对应订阅
  appEvent.notification('addEvent', {
    value: index,
    tag: tag2,
  });
}, 1000);

react-example

eventContext.tsx

import { AppEvent } from 'app-event';

// eventName: notification-value
interface Event {
  printLog: string;
  scrollValueEvent: number;
}

// 共享event-context
export const EventContext = createContext<AppEvent<EventName>>(new AppEvent());

/**
 * 全局事件
 * @param props
 * @returns
 */
export const EventProvider = (props: Props) => {
  const event = new AppEvent<EventName>({ debug: false });
  return (
    <EventContext.Provider value={event}>
      {props.children}
    </EventContext.Provider>
  );
};

App.tsx

import { useCallback, useEffect, useState, useContext } from 'react';

function App() {
  // 时间戳
  const [timestamp, setTimestamp] = useState('');
  // scrollValue
  const [scrollValue, setScrollValue] = useState(0);
  // 获取context
  const appEvent = useContext(EventContext);

  // 点击事件触发
  const clickHandle = useCallback(() => {
    const time = new Date().getTime();
    appEvent.notification('printLog', {
      value: `${time}`,
    });
  }, []);

  // 监听点击
  useEffect(() => {
    window.addEventListener('click', clickHandle);
  }, [clickHandle]);

  // 自定义监听事件
  useEffect(() => {
    // 监听printLog
    appEvent.addListen('printLog', (value) => {
      setTimestamp(value ?? '');
    });
    // 监听scrollValueEvent
    appEvent.addListen('scrollValueEvent', (value) => {
      setScrollValue(value ?? 0);
    });
    // 移除监听
    return () => {
      window.removeEventListener('click', clickHandle);
      appEvent.removeListen('printLog');
      appEvent.removeListen('scrollValueEvent');
    };
  }, [clickHandle]);

  // 滚动事件触发
  const onScroll = useCallback((e: any) => {
    const el: HTMLDivElement = e.target as any;
    appEvent.notification('scrollValueEvent', {
      value: el.scrollTop,
    });
  }, []);

  // 点击按钮移除【printLog】事件
  const removeClick = useCallback(() => {
    appEvent.removeListen('printLog');
  }, []);

  // 点击按钮移除【printLog】事件
  const addClick = useCallback(() => {
    appEvent.addListen('printLog', (value) => {
      setTimestamp(value ?? '');
    });
  }, []);

  return (
    <div
      style={{
        height: '100vh',
        overflowY: 'scroll',
      }}
      onScroll={onScroll}
    >
      <div
        style={{
          height: '200vh',
        }}
      >
        <h1>value: {timestamp}</h1>
        <h1>scrollValue: {scrollValue}</h1>
        <div>
          <button onClick={removeClick}>remove: printLog</button>
          <br />
          <button onClick={addClick}>add: printLog</button>
        </div>
      </div>
    </div>
  );
}

export default App;