场景:
三组开关按钮 分别是
[上班/下班] [工作/休息] [派单/停止]有三个窗口要能共享
上班工作两个状态,且有派单就不能点击休息,必须关闭所有派单
状态解读
当前状态变为【xx】时:
【上班】 => work: true,assign: ture, [工作/休息] => 休息, 「 派单/停止」 => 停止
【下班】 => work: false,assign: false[工作/休息] => 工作, 「 派单/停止」 => 派单
窗口>=1时,需要把所有的【派单】状态改为【派单】,才可以点击休息。
方案设计
1、 BroadcastChannel 发送消息,实现不同窗口之间共享数据
2、 localstroage 存储窗口信息
3、 window.addEventListener(unload)负责删除窗口关闭的数据。
为什么不使用SeesionStorage
只存在于当前tab页 -----数据无法共享给同域名其他的tab
为什么不只使用LocalStorage
当有tab页关闭,localStorage中的数据不会被删除 ---需要当前窗口的数据被删除
代码实现
// 1 编写BroadcastChannel hook
export const useBroadcastChannel = ({
channelName,
onMessage,
}: UseBroadcastChannelParams) => {
useEffect(() => {
if (onMessage) {
const channel = new BroadcastChannel(channelName);
channel.onmessage = (event) => {
onMessage(event.data);
};
return () => {
channel.close();
};
}
}, [channelName, onMessage]);
const postMessage = (data: any) => {
const channel = new BroadcastChannel(channelName);
channel.postMessage(data);
channel.close();
};
return { postMessage };
};
// 2、在需要的地方注册发送者
const { postMessage } = useBroadcastChannel({
channelName: 'currentWorkStatusChannel',
});
postMessage({type,status})
// 3、接受消息 更新其他窗口的状态
useBroadcastChannel({
channelName: 'currentWorkStatusChannel',
onMessage:(data) => {
const {type,status} = data;
switch(type) {
'上班':
....
break;
'休息':
...
break;
default:
}
}
});
// 4、unload
const onUnload = () => {
setTab(xx, false);
};
// 检测关闭窗口时的状态切换
useEffect(() => {
window.addEventListener('unload', onUnload);
return () => {
window.removeEventListener('unload', onUnload);
};
}, []);
// 5、localStorge设置
const getTab = () => {
try {
const keys = localStorage.getItem('TAB');
return keys ? JSON.parse(keys) : [];
} catch (e) {
return [];
}
};
export const hasNotQueue = () => getTab().length === 0;
/**
* @param id
* @param status 添加还是删除
*/
export const setWorkQueue = (id: string | number, status: boolean) => {
const keys = getTab();
if (!status) {
localStorage.setItem(
'TAB',
JSON.stringify(keys.filter((key: string | number) => key !== id)),
);
return;
}
if (keys.includes(id)) {
return;
}
localStorage.setItem('TAB', JSON.stringify([...keys, id]));
};