0.0.4 • Published 2 years ago
custom-app-event v0.0.4
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;