一、什么是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;