需求描述
vue 新项目中有一个订单消息提醒搜索结果页,每一条信息有已阅和没有读状态,点一下信息用到 window.open 开启一个新的电脑浏览器标签页跳转订单搜索结果页,订单搜索结果页内有项操作是查询信息,会弹出窗口显现出具体具体内容,进入这个弹出窗口就表明客户早已见到消息了,这时想去调后端接口改动信息显示为已阅。
必须实现用户已阅现阶段消息时,前边一个订单消息提醒搜索结果页的已阅/未读状态实时同步。
能想到的控制方式
- 1、直接使用计时器 setInterval 不断轮循调后端接口查全新情况
- 2、用 vuex 完成全局状态分享
- 3、用 localStorage 完成信息共享
第1种非常简单,但是有点儿 low 立即 pass 没了。第2种乍一看仿佛能够实现,事实上你来试一下就能发现难题,vuex 是不可以跨标签页互通的,每一个标签页中的 vuex 案例是单独的,你更改了现阶段标签页中的 vuex 里数据信息,别的标签页并不是受影响,在网上找到一个软件 vuex-shared-mutations,但是看了一下近期维护保养或是4年之前,因此也立即 pass 了。
然后用第3种完成了,他在 localStorage 里存一个标志,之后在必须同步数据页面开一个 storage 事件监视,去监视本地缓存的改变,假如是目标产生变化,立即重新获得数据下载就行了,具体 demo 编码:
消息提醒搜索结果页
<template>
<div>
<p v-for="(item, index) in noticeList" :key="index">信息{{ index 1 }}:{{ item.title }}</p>
</div>
</template>
<script>
export default {
data() {
return {
noticeList: [
{ title: '我就是第一条信息' },
{ title: '我就是第二条信息' },
]
}
},
created() {
// 跨标签页监视
window.addEventListener('storage', this.storageChange)
},
beforeDestroy() {
window.removeEventListener('storage', this.storageChange)
},
methods: {
storageChange(e) {
if (e && e.key == 'targetKey' && e.newValue) {
// 在这儿同步数据
}
},
}
}
</script>
订单搜索结果页
<template>
<div>
<p @click="handleRead">读信息</p>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
handleRead() {
localStorage.setItem('targetKey', 1)
},
}
}
</script>
效果也是完成了,最后我觉得还是不是很满意,在微信群里了解了一圈,果真有大发觉,postMessage 和 BroadcastChannel 这俩浏览器新 api 是能够完成跨标签页通讯的,postMessage 还能实现跨源通讯,一般用在和 iframe 通讯较多。
最终版
最后试了 BroadcastChannel 版本号:
接受信息:
const BC = new BroadcastChannel('notice')
BC.onmessage = (e) => {
console.log('信息来啦:', e)
}
// 中断连接
// BC.close()
发送信息:
const BC = new BroadcastChannel('notice')
BC.postMessage('传出信息,赶快去同步数据吧')
// 中断连接
// BC.close()
有关文本文档
- BroadcastChannel
- postMessage