UNPKG

custom-app-event

Version:

基于typescript, 实现一个简单的event库,快速集成发布订阅模式

231 lines (195 loc) 5.08 kB
# Event 库,快速实现发布订阅模式 ## 参数 ```tsx // 事件名: 通知的值的类型 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 ```tsx 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 控制更加细小粒度发布,订阅,通知 ```tsx // 添加订阅 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 ```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 ```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; ```