前端跨标签页通信如何实现
一、使用 BroadcastChannel API实现
MDN的解释:
BroadcastChannel 接口表示给定源的任何浏览上下文都可以订阅的命名频道。它允许同源的不同浏览器窗口、标签页、frame 或者 iframe 下的不同文档之间相互通信。消息通过 message 事件进行广播,该事件在侦听该频道的所有 BroadcastChannel 对象上触发,发送消息的对象除外。
使用方法如下:
数据传输页
<template>
<div class="test">
传输页
<el-button type="primary" @click="handleAdd">新增表格</el-button>
</div>
</template>
<script setup>
import { ref,reactive,provide } from 'vue';
let list = [];
const sendMsg = new BroadcastChannel('send_Msg');//频道名称要与接收页一致
function handleAdd(){
list.push({
id: Date.now(),
name: '张三',
age: 18,
sex: '男',
address: '北京市'
});
sendMsg.postMessage(list);
}
</script>
数据接收页
<template>
<div>
接受页
<el-table :data="data" border style="width:500px">
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="age" label="年龄" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
</div>
</template>
<script setup>
import { ref,reactive, defineComponent } from 'vue'
const data = ref([]);
const channel = new BroadcastChannel('send_Msg');
channel.onmessage = function(e) {
console.log(e);
data.value = e.data;
};
</script>
效果如下

二、监听localStorage事件
因为同源页面间localStorage是共享的,所以可以监听storage事件实现
传输页
function handleAdd(){ list.push({ id: Date.now(), name: '张三', age: 18, sex: '男', address: '北京市' }); localStorage.setItem('list', JSON.stringify(list)); }
接受页
const data = ref([]); window.addEventListener('storage',function(e){ console.log(e) data.value = JSON.parse(e.newValue) })
效果如下:

三、 使用 SharedWorker 连接多个不同的页面
SharedWorker 接口代表一种特定类型的 worker,可以从几个浏览上下文中访问,例如几个窗口、iframe 或其他 worker。这些页面必须是同源的(相同的协议、host 以及端口)
传输页
<template>
<div class="test">
传输发送页
<el-button type="primary" @click="handleAdd">新增表格</el-button>
</div>
</template>
<script setup>
import { ref, reactive, provide } from 'vue';
let list = [];
const sendMsg = new SharedWorker(new URL('./worker.js', import.meta.url)); // 创建一个共享worker
const port = sendMsg.port;
port.onmessage = function (event) {
console.log('接收到来自worker的消息:', event.data);
}
function handleAdd(){
list.push({
id: Date.now(),
name: '张三',
age: 18,
sex: '男',
address: '北京市'
});
port.postMessage(list);
}
</script>
<style lang="scss" scoped>
</style>
接受页
<template>
<div>
接受页
<el-table :data="data" border style="width:500px">
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="age" label="年龄" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
</div>
</template>
<script setup>
import { ref,reactive, defineComponent } from 'vue'
const data = ref([]);
const worker = new SharedWorker(new URL('./worker.js',import.meta.url));
worker.port.start();
worker.port.onmessage = function (e) {
console.log('接受数据',e);
if(e.data){
data.value = e.data;
}
};
setInterval(()=>{
worker.port.postMessage("get");
},2000);
</script>
浙公网安备 33010602011771号