VUE中使用BroadcastChannel实现同源多页面实时通信
使用BroadcastChannel广播通信
准备工作:
1.channel.js文件,内容如下
const Channel = {
/**
* BroadcastChannel对象Map
*/
channelMap: new Map(),
/**
* 发送消息,重载方法,可直接调用,省略对象实例化操作
* @param {*} channelName 通道名称,用以区分不同的通道
* @param {*} object 消息体
*/
send: (channelName, object) => {
if (!Channel.channelMap.has(channelName)) {
let channel = new BroadcastChannel(channelName);
Channel.channelMap.set(channelName, channel);
}
Channel.channelMap.get(channelName).postMessage(object);
},
/**
* 监听消息,重载方法,可直接调用,省略对象实例化操作
* @param {*} channelName 通道名称,用以区分不同的通道
* @param {*} callback 回调函数
*/
listen: (channelName, callback) => {
if (!Channel.channelMap.has(channelName)) {
let channel = new BroadcastChannel(channelName);
Channel.channelMap.set(channelName, channel);
}
Channel.channelMap.get(channelName).onmessage = ({ data }) => {
callback(data);
};
},
/**
* 通道关闭
* @param {*} channelName 通道名称,用以区分不同的通道
*/
close: (channelName) => {
if (Channel.channelMap.has(channelName)) {
Channel.channelMap.get(channelName).close();
Channel.channelMap.delete(channelName);
}
},
/**
* 通道枚举,定义业务中需要用到的所有通道名称枚举,可根据业务需求无限扩容
*/
channelEnum: {
REMOVE_TAB: { name: 'removeTab', comment: 'tabs标签移除时,用以通知被关闭页面,进行诸如实例、注册事件等的销毁工作' },
GLOBAL_LOADING: { name: 'globalLoading', comment: '全局加载动画' },
TEST: { name: 'TEST_Channel', comment: 'TEST_Channel' },
},
};
export default Channel
2.选择是新打开页签还是新开窗口(下面代码二选一即可)
/**
* 打开新窗口
*/
openNewWindow () {
// 打开新窗口
// 新窗口居中
let left = ((window.screen.width / 2) - 180) / 2
// 新窗口的宽度
let width = (window.screen.width / 2) + 180
// 新窗口要设置的参数
let params = `height=${window.screen.height},width=${width},top=0,left=${left},toolbar=no,menubar=no,scrollbars=no,resizable=yes,location=yes,status=no`
window.open(`/testPage/${this.title}/${this.id}/${this.type}/${this.date}`,'_blank',params)
},
/**
* 打开新页签
*/
openNewTab() {
// 打开新标签
let routeData = this.$router.resolve(({
// path 要跳转的路由地址
path: '/testPage',
// query 要传递的参数
query: {
title: this.title,
id: this.id,
type: this.type,
date: this.date,
}
}))
window.open(routeData.href, '_blank')
},
代码编写与测试
第一步:
引入channel.js文件到项目中,再引入到页面中(生产者与消费者都需要引入)


第二步:
生产者代码:
send() {
console.log('-------send-------')
Channel.send(Channel.channelEnum.TEST.name, '发消息了。。。:'+new Date())
},
消费者代码:
mounted() {
Channel.listen(Channel.channelEnum.TEST.name, this.listen)
},
methods:{
listen(data) {
console.log('-------listen-------')
console.log('收到消息:', data);
},
}
第三步:
测试效果


浙公网安备 33010602011771号