我是一名初学者,我在使用Tauri+vue3+pinia开发桌面应用的时候,发现窗口间的Pinia对象是独立的,但是我现在的需求是,Pinia中的部分数据是可以窗口间同步的(比如:有一个count属性,当其中一个窗口改变时,其他窗口同步改变)。
这是我目前的实现方法
import { createPinia } from 'pinia';
import { emit, listen, type Event } from '@tauri-apps/api/event';
import { appWindow } from '@tauri-apps/api/window';
export default defineNuxtPlugin((nuxtApp: any) => {
const pinia = createPinia();
nuxtApp.vueApp.use(pinia)
pinia.use(syncDataWithMainWindow);
})
/** 窗口间数据同步 所有数据和主窗口同步 */
export async function syncDataWithMainWindow(context: any) {
watch(context.store, () => {
if (!context.store.watchEnabled.value) {
context.store.setWatchEnabled(true)
return;
}
emit('syncStore', context.store);
}, { flush: 'post' });
listen('syncStore', (event: Event<any>) => {
if (context.store.label.value === event.payload.label._value) return; // 忽视自己发送的事件
// 非主窗口停止监听转发数据,只有主窗口接收到数据会进行转发
if (appWindow.label !== 'main') {
context.store.setWatchEnabled(false);
}
context.store.window_sync_source.value = event.payload.label._value; // 记录数据来源
context.store.syncCount.value = event.payload.syncCount._value
})
}
目前存在的问题是,在代码同步完成后,会触发watch,然后陷入同步的循环,虽然我做了watch开关处理,但是窗口间的数据同步本身就是非同步的过程,这样做依然会陷入循环,而且这样做感觉埋了一个惊天大bug。
期望的数据交换:
大家有没有更好的方法实现
曾经的尝试:
#region 所有窗口之间相互同步,资源消耗大
export async function syncDataBetweenWindows(context: any) {
await initSync(context);
updateSync(context);
}
function initSync(context: any) {
return new Promise((res, rej) => {
let timeout = setTimeout(() => {
rej(false);
throw new Error("页面初始化获取全局Store超时");
}, 3000);
once('initStoreSync', (event: any) => {
sync(event, context);
clearTimeout(timeout);
res(true);
})
listen('initStore', (event: any) => {
if (event.payload.label === appWindow.label) return;
emit('initStoreSync', {
data: {
store: context.store,
label: appWindow.label
}
})
})
emit('initStore', { label: appWindow.label });
})
}
function updateSync(context: any) {
watch(context.store, () => {
if (context.listenUpdate) {
context.listenUpdate = false;
return;
}
emit('storeSync', {
data: {
store: context.store,
label: appWindow.label
}
})
})
listen('storeSync', async (event: any) => {
sync(event, context);
})
}
function sync(event: any, context: any) {
if (event.payload.data.label == appWindow.label) return;
for (const key in event.payload.data.store) {
if (!Object.prototype.hasOwnProperty.call(event.payload.data.store, key)) continue;
if (key.substring(0, 4) != 'sync') continue;
context.listenUpdate = true;
context.store[key].value = event.payload.data.store[key]._value;
console.log('数据同步');
}
}
#endregion
所有窗口之间的数据同步,在store中,使用sync开头的属性变量名会被标记为需要同步的数据。这样做同样会陷入循环,导致程序崩溃,而且感觉这样做很消耗资源。
解决方法:不用vue的监听数据的更新,Pinia有一个$onAction函数,用来监听Store的Action是否被调用
let init: boolean = false;
let syncObj: any = {};
/** 窗口间数据同步 所有数据和主窗口同步 */
export async function syncDataWithMainWindow(context: PiniaPluginContext) {
if (!init) {
if (appWindow.label !== 'main') {
emit('getStore', syncObj);
} else {
listen('getStore', () => {
emit('syncStore', syncObj);
})
}
}
context.store.$onAction((context2) => {
if (context2.name === 'sync') return;
context2.after(() => {
emit('syncStore', syncObj)
})
})
if (init) return;
init = !init;
watch(context.store.syncKeyList.value, () => {
syncObj = context.store.syncList.value;
}, { flush: 'post' })
listen('syncStore', (event: Event<any>) => {
if (event.windowLabel === appWindow.label) return;
for (const key in event.payload) {
if (!Object.prototype.hasOwnProperty.call(event.payload, key)) return;
const item = event.payload[key];
context.store.syncList.value[key].value = item._value;
}
})
}
vue3+pinia+piniaPluginPersistedstate持久化sessionStorage缓存,页面中某个按钮点击单独open一个浏览器新窗口,执行某些操作后,更新pinia数据,更新后主窗口和新窗口的pinia数据不同步嘛? 源窗口id已更新,之前打开的新窗口还是显示的新窗口打开时的id 源窗口更新后的id值: 新窗口还是显示的新窗口打开时的id值: 如果不同步的话,请问有啥解决
我正在构建一个具有以下目标的 Flink 应用程序: 将事件收集到键控的非活动触发会话窗口中 尽早发出输入事件的副本,并通过会话引用进行增强 打开和关闭会话时发出会话更新以及收集的会话统计信息(在会话关闭时) 通过滚动窗口,我已经能够实现上述目标,但在会话窗口中我没有成功。 我的窗口处理代码如下 来生成我正在使用的输入 和 当我使用会话窗口执行时,会出现以下异常: 希望我错过了一个技巧,因为无法使
本文向大家介绍如何在JavaScript中实现多态?,包括了如何在JavaScript中实现多态?的使用技巧和注意事项,需要的朋友参考一下 多态性 多态 是面向对象编程(OOP)的宗旨之一。它有助于设计对象,使其可以与特定提供的对象共享或覆盖任何行为。多态性 利用继承的 优势来实现这一点。 在以下示例中,子对象(例如“板球”和“网球”)已覆盖从父对象“游戏”调用的“选择”方法,并分别返回了新字符串
我开始着手一个JavaFX项目,在这个项目中,我想添加一个复制的文本,而不必更改驱动程序中的格式和图像(它应该像open office一样工作)。图像应该能够放置在文本中不同的位置。因此,我需要一个可以处理rtf格式的控制字段。 为此,我找到了RichTextFX。文档中解释了如何使用Maven或Grandle运行RichTextFX。我不使用Maven或Grandle,因此我想知道是否有可能在不
请把这个问题当作严格的教育问题来处理。我仍然有兴趣听到新的答案和想法来实现这一点 如何用JavaScript实现双向数据绑定? 通过与DOM的数据绑定,我的意思是,例如,拥有一个带有属性的JavaScript对象。然后拥有一个DOM元素(例如),当DOM元素发生变化时,也会发生变化,反之亦然(也就是说,我指的是双向数据绑定)。 在简单的JavaScript中实现这一点的一些基本技术是什么? 具体来
如何在thymeleaf超文本标记语言文档中使用户data-Target="#userId"。例如,在任何JSP或任何超文本标记语言中, 我如何在thymeleaf HTML文档中编写。这样地? 例外情况是: