Pinia多Store同时操作时$subscribe遗漏mutation问题排查
问题分析与解决方案
你的问题核心出在Pinia插件的几个关键细节处理上,结合代码逐一拆解:
核心问题点
- 未区分不同Store的存储标识:原插件里的
storeName和storeId属于未定义变量,若实际代码中是硬编码值,会导致所有Store的状态都写入同一个IndexedDB位置,后执行的ProjectStore操作会直接覆盖GoalStore的存储请求。 - 语法错误阻断逻辑:序列化代码多了一个右括号:
const toStorage = serializer.serialize(state));,这个错误会直接抛出异常,导致GoalStore的存储逻辑根本无法执行(若你屏蔽了控制台错误,就会误以为是订阅失效)。 - 异步操作未处理竞态:
ofcDB.set是异步操作,但原回调未用await等待完成,多个Store的存储请求同时触发时,容易引发竞态导致部分请求失败。 - State初始化错误:GoalStore中
goals: null的初始化方式,会导致this.goals.push(Goal)直接报错,虽然你说ProjectStore的操作生效了,但这个错误会中断当前代码逻辑,建议初始化为空数组goals: []。
修正后的插件代码
import ofcDB from 'boot/indexeddb'; import { serializer } from './your-serializer-path'; // 确保导入序列化工具 export function IndexedDbPlugin(context) { // 获取当前Store的唯一ID,作为存储的唯一标识 const currentStoreId = context.store.$id; context.store.$subscribe(async (mutation, state) => { try { // 修正语法错误,序列化当前Store的状态 const serializedState = serializer.serialize(state); // 用Store的ID作为Collection或Doc的标识,确保每个Store数据独立存储 await ofcDB.collection(currentStoreId).doc(currentStoreId).set(serializedState); } catch (err) { console.error(`[IndexedDB插件] 存储Store ${currentStoreId} 失败:`, err); } }, { detached: true }); // 可选:detached设为true,确保组件卸载后订阅仍生效 }
额外注意事项
- 若你的序列化工具只是简单处理,也可以直接用
JSON.stringify(state)替代serializer.serialize(state)。 - 检查GoalStore的
createItem方法,确保this.goals已初始化为空数组,避免push操作抛出异常。
内容的提问来源于stack exchange,提问作者Toni Benitez
相关产品推荐
相关产品推荐

