前端跨页面通信 的几种思路

2023-08-07  本文已影响0人  爱学习的小仙女早睡早起

同源页面

A页面打开B页面,B页面的业务进行完成后,B页面需要触发A页面的某刷新方法

广播模式,页面将消息通知给一个中转,中转再通知给各个页面。中转可以是一个 BroadCast Channel 实例、一个 Service Worker 或是 LocalStorage。

BrocastChannel

BrocastChannel可以实现同源下浏览器不同窗口,tab页,frame或frame下的浏览器上下文之间的通信。

// a页面
var bc = new BroadcastChannel('qwer')
bc.postMessage('发送数据')

// b页面
var bc = new BroadcastChannel('qwer')
bc.onmessage = function(e) {
  console.log(e)
}
/** 消息发送后,所有连接到该频道的 BrocastChannel对象上都会触发 meaasge事件,
该事件没有默认行为,可以使用`onmessage`事件处理程序来定义一个函数处理消息
**/

LocalStorage

LocalStorage是前端常用的本地存储,当LocalStorage变化是,会触发storage事件,发送消息时,将消息写入LocalStorage中,然后在各个页面中,通过监听storage事件即可收到通知。

// a页面
window.addEventListener('storage', function(e) {
  console.log(e)
})

// b页面
localStorage.setItem('qwer', 10000)



1、A页面的mounted里监听

    let CHANNEL_CODE = 'refreshTable'
    this.listenChannel = new BroadcastChannel(CHANNEL_CODE);
    this.listenChannel.onmessage = (res) => {
        // console.log(res);
        if (res.data.success) {
            that.bs.queryTableList();
        }
    };


// 注意在A页面里这里要销毁
beforeDestory(){
    this.listenChannel.close();
}

2、B页面触发

        let CHANNEL_CODE = 'refreshTable'
          let listenChannel = new BroadcastChannel(CHANNEL_CODE);
          listenChannel.postMessage({
            type: 'refreshTable',
            success: 'true' + Math.random()
          });
          console.log("触发刷新数据" )
          listenChannel.close();

Vuex

如果是vue项目
还可以考虑将监测数据存入到store里,在A页面的computed拿到检测数据,然后watch数据的变化;


或者在浏览器缓存存储检测数据,在A页面定时器获取检测数据来判断变化

通过事件的发布订阅模式

代码实现
utils/msgCenter.js

class msgCenter {
    constructor() {

    }

    msgObj = new Object();

    on = (msgName, func) => {
        this.msgObj[msgName] = func;
    }

    one = (msgName, func) => {
        this.msgObj[msgName] = func;
    }

    emit = (msgName, data) => {
        if (!Object.prototype.hasOwnProperty.call(this.msgObj, msgName)) return;
        this.msgObj[msgName](data);

    }

    off = (msgName) => {
        if (!Object.prototype.hasOwnProperty.call(this.msgObj, msgName)) return;
        delete this.msgObj[msgName];
    }

}

export default new msgCenter()

使用:

发布事件
              import $SLMC from "@/utils/msgCenter";

              $SLMC.emit("refreshTable", data);  

订阅事件
              import $SLMC from "@/utils/msgCenter";

              $SLMC.on("refreshTable", this.refreshTable);
上一篇 下一篇

猜你喜欢

热点阅读