BroadcastChannel:同源浏览器不同标签页或窗口,发送订阅消息

307 阅读1分钟

需求:

我们现在系统支持多个商城,融合到一个系统中,就是当前这个系统,用户在切换商城的时候,如果这个时候用户是开启了多个标签页,在A页面切换商城,需要在B、C等页面有弹框提示,必须要刷新页面

image.png

差不多就是这样一个效果

动画.gif

先在页面写个按钮和数字,由于多个页面共享一个num,num给存储到localStorage中

    <el-button @click="add">add</el-button>
    <p>{{ num }}</p>
  data() {
    return { num: 0 }
  },
  created() {
    const num = +localStorage.getItem('num')
    this.num = num
  },
  methods: {
    add() {
      this.num++
      localStorage.setItem('num', this.num)
    },
  }

这样,在A页面点击按钮后,切换到B、C页面,刷新页面,num会更新

接下来加入BroadcastChannel,完整代码

BroadcastChannel/index.vue

<template>
  <div class="broadcast-channel">
    <el-button @click="add">add</el-button>
    <p>{{ num }}</p>
    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
      :show-close="false"
      :close-on-click-modal="false"
    >
      <span>数据发生变化,请刷新后操作</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleRefresh">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  name: 'BroadcastChannel',
  data() {
    return { num: 0, channel: null, dialogVisible: false }
  },
  created() {
    const num = +localStorage.getItem('num')
    this.num = num
    this.channel = new BroadcastChannel('test')
    this.channel.addEventListener('message', event => {
      console.log('event', event.data)
      this.dialogVisible = true
    })
  },
  beforeDestroy() {
    if (this.channel) {
      this.channel.close()
      this.channel = null
    }
  },
  methods: {
    add() {
      this.num++
      localStorage.setItem('num', this.num)
      // this.channel = new BroadcastChannel('test')
      this.channel.postMessage(this.num)
    },
    handleRefresh() {
      this.dialogVisible = false
      window.location.reload()
    }
  }
}
</script>

更多js跨标签页通信方式参考:juejin.cn/post/731535…

BroadcastChannel注意事项:

1、只有同源才能接收到消息

分别在192.168.1.89:10001devops.aliyun.com写上接收

image.pngimage.png

当我在192.168.1.89:10001中发送消息时,只有192.168.1.89:10001能接收到

image.pngimage.png

2、当监听和发送使用同一个broadcastChannel实例的时候,发送的消息不能被监听到

image.png

如果你觉得这篇文章对你有用,可以看看作者封装的库xtt-utils,里面封装了非常实用的js方法。如果你也是vue开发者,那更好了,除了常用的api,还有大量的基于element-ui组件库二次封装的使用方法和自定义指令等,帮你提升开发效率。不定期更新,欢迎交流~