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); }, }

第三步:

   测试效果

 

posted @ 2025-03-21 17:32  东峰叵,com  阅读(176)  评论(0)    收藏  举报