一、什么是Broadcast Channel
MDN 中解释如下:
允许同源的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。
二、Broadcast Channel 与 window.postMessage区别
BroadcastChannel 只能用于同源的页面之间进行通信,而window.postMessage 却可以用于任何的页面之间,所以,跨域的情况,需要使用 window.postMessage 来处理。
三、如何使用
1、创建实例
const channel = new BroadcastChannel('test');
2、监听消息
// 1、使用addEventListener监听
function onMessage(event) {console.log(event)
}
channel.addEventListener('message', onMessage);// 2、直接调用实例上的 onmessage
channel.onmessage = function(event) {console.log('event:', event.data);
};
3、监听错误消息
// 1、使用addEventListener监听
function onMessageError(event) {console.log(event)
}
channel.addEventListener('onmessageerror', onMessageError);// 2、直接调用实例上的 onmessageerror
channel.onmessageerror = function(event) {console.log('error:', event);
};
4、发送消息
channel.postMessage({type:'test'});
5、关闭广播监听
// 1、如果上边监听消息是通过实例上调用onmessage
channel.close();// 2、如果上边监听消息通过addEventListener
function onMessage(event) {console.log(event)
}
channel.removeEventListener('message', onMessage)
四、封装通用方法
比如项目中封装统一的 utils
const channel = new BroadcastChannel('test');
// 发送消息
export function postMessage(message: object) {console.log(channel, 'channel');channel.postMessage(message);
}// 监听消息
export function listenMessage(callback) {function onMessage(event) {callback && callback(event);}channel.addEventListener('message', onMessage);return () => {channel.removeEventListener('message', onMessage)}
}
1、在 react 项目中监听消息
import React, { useEffect, useState } from 'react'
import { listenMessage } from './utils'export default function Home() {const [age, setAge] = useState('10');useEffect(() => {function getMessage(e) {const {data} = e;setAge(data?.data);}const channel = listenMessage(getMessage);// 清除副作用return channel;}, [])return (<div><div>{age}</div></div>);
}
2、在 react 项目中发送消息
import { postMessage } from './utils';
function App() {function hanldePostMessage() {postMessage({ type: 'update', data: '20' })}return (<div><div onClick={hanldePostMessage}>点击发送消息</div></div>);
}export default App;