前言
在开发管理后台页面的时候,会遇到这样一种需求:有一个列表页面,一个新增按钮,一个新增页面,点击新增按钮,在一个新的标签页中打开新增页面。并且,新增后要自动实时的更新列表页面的数据。
如果用Vue/React等现代SPA(单页面)框架,我们很容易想到使用状态管理库来实现,但如果是两个不同的html
页面呢,例如一个是list.html
,一个是detail.html
,你可能会想到使用websocket
或EventSource
,但这实在是有点大材小用了。
上干货
最近看了渡一袁老师的视频,学到一个监听storage
事件,能够监听别的标签页改动了localStorage
中的任何一个key
。
可以看到在别的标签页改变了storage中的一个key
,即可触发监听,并且能知道改动了哪个key
,以及最新的value
值。这就相当于是一个标签页往另一个标签页发送消息。
有了这个,这样我们就可以实现标签页之间的通信了。
可以写一个通用的js,这个js只需要实现两个函数。一个用来发送消息,一个用来监听消息。
发送消息的函数
思路:
- 参数1:接收一个type类型,用来表示做了什么操作
- 参数2:接收一个操作的数据payload
- 函数体:用type作为key,payload作为value,保存到localStorage
- 返回值:无
前面说了,只有某个key的value值改变了才会触发,那么多次新增一样的数据,就不会触发,所以需要给保存的数据附加一个随机数。
/**
* @description: 发送消息
* @param {*} type 操作类型
* @param {*} payload 操作的数据
* @return {*} null
*/
export function sendMsg(type, payload) {
localStorage.setItem(
type,
JSON.stringify({
payload,
temp: +new Date()
})
)
}
监听消息的函数
思路:
- 参数:接收一个回调函数
- 函数体:监听
storage
事件,将监听到的数据回传给回调函数 - 返回值:返回一个函数用来取消监听
/**
* @description: 监听消息
* @param {*} handle 回调函数
* @return {*} 取消监听的函数
*/
export function listenMsg(handle) {
const storageHandler = (e) => {
const data = JSON.parse(e.newValue)
handle(e.key, data.payload)
}
window.addEventListener('storage', storageHandler)
return () => {
window.removeEventListener('storage', storageHandler)
}
}
来测试一下
test.html
index.html
看看效果
不得不说,真是太妙了!