vue3+pinia+piniaPluginPersistedstate持久化sessionStorage缓存,页面中某个按钮点击单独open一个浏览器新窗口,执行某些操作后,更新pinia数据,更新后主窗口和新窗口的pinia数据不同步嘛?
源窗口id已更新,之前打开的新窗口还是显示的新窗口打开时的id
源窗口更新后的id值:
新窗口还是显示的新窗口打开时的id值:
如果不同步的话,请问有啥解决办法嘛?
vue3+pinia+piniaPluginPersistedstate持久化sessionStorage缓存,页面中某个按钮点击单独open一个浏览器新窗口,执行某些操作后,更新pinia数据,更新后主窗口和新窗口的pinia数据不同步嘛?
源窗口id已更新,之前打开的新窗口还是显示的新窗口打开时的id
源窗口更新后的id值:
新窗口还是显示的新窗口打开时的id值:
如果不同步的话,请问有啥解决办法嘛?
在pinia-plugin-persistedstate插件之上在扩展广播通道,不知道有没有bug
import { useBroadcastChannel } from '@vueuse/core';
import { watch } from 'vue';
export function createSyncPlugin() {
return ({ store }) => {
const { data, post } = useBroadcastChannel({ name: `pinia-sync-${store.$id}` });
// 监听来自其他窗口的消息并更新 store
watch(data, (newValue) => {
if (newValue) {
const parsedData = JSON.parse(newValue as string);
store.$patch(parsedData);
}
});
// 监听本窗口内的 store 变化并广播消息
store.$subscribe((_mutation, state) => {
const deserializeData = JSON.stringify(state);
post(deserializeData);
});
};
}
import { createPinia } from 'pinia';
import { createPersistedState } from 'pinia-plugin-persistedstate';
import { createSyncPlugin } from './plugins/pinia-plugin-sync';
const store = createPinia();
store.use(createPersistedState());
store.use(createSyncPlugin());
export { store };
export * from './modules/xxxx1';
export default store;
import { defineStore } from 'pinia';
export const useSettingStore = defineStore('setting', {
state: () => {
theme: 'dark'
},
getters: {},
actions: {},
persist: true, // 数据持久化
});
1. main.js中:window.vueGlobalProperties = app.config.vueGlobalProperties;
2. 子窗口中定义,将父窗口的pinia赋值给子窗口:
const parentPinia = window.opener.vueGlobalProperties.$pinia;
3. 可以通过监听父窗口store状态发生变化时,给子窗口发送事件的方式,实现同步更新。
// 新打开的子窗口
let NewWin = window.open(url);
// 父窗口监听pinia数据有变化时,更新子窗口
store.$subscribe(() => {
if (NewWin) {
NewWin.postMessage("updateStore")
}
})
// 子窗口接收更新事件
window.onMessage = event => {
if (event.data === "updateStore") {
store.$patch(parentPinia.state.value[k])
}
}
刚好也遇到了同源多页签/窗口之间共享数据的需求,找到了这个Broad Cast Channel 通信API。我先立个Flag,等有生之年我发布了这个 pinia 插件发布了再来,补充。估计最终实现逻辑与上面两位答主的思路不会有区别,都是发布订阅
找到了一个已经实现的插件,看了源码思路相同,甚至同步实现了 Storage的同步 pinia-persist-share
6 回答2.9k 阅读✓ 已解决
8 回答4.6k 阅读✓ 已解决
6 回答3.3k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
6 回答2.3k 阅读
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
不会同步。因为
sessionStorage
并不是响应式的,并且新窗口的pinia
是一个新的实例,数据更新后不同的pinia
实例之间并不能同步。若两个窗口之间需要通信,可通过如下示例实现:或者将
dispatchEvent
改为winodw.postMessage亦可。需要注意的是,新窗口不能刷新,否则可能会导致无法通信。