状态管理
概述
项目使用 Pinia 3 作为状态管理方案,配合 pinia-plugin-persistedstate 实现状态持久化。所有 Store 定义在 src/stores/ 目录下。
Store 概览
| Store | 文件 | 职责 |
|---|---|---|
settings | stores/settings.ts | 主题/布局/偏好等系统配置,持久化并带 schema 版本迁移 |
user | stores/user.ts | 用户详情 + 菜单,登录后拉取并注册动态路由(触发字典加载) |
dict | stores/dict.ts | 数据字典(状态/性别等枚举),运行时按 dict_type 动态分组 |
tab | stores/tab.ts | 已打开页签列表 |
lock | stores/lock.ts | 锁屏状态与可选 PIN(散列存储),支持空闲自动锁定 |
socket | stores/socket.ts | WebSocket 连接状态 |
持久化配置
项目使用 pinia-plugin-persistedstate 将关键状态持久化到 localStorage,避免页面刷新后数据丢失。
typescript
// stores/settings.ts
export const useSettingsStore = defineStore('settings', {
state: () => ({
schemaVersion: 2,
themeMode: 'light',
layoutMode: 'side',
primaryColor: '#18a058',
// ... 60+ 配置项
}),
persist: {
key: 'app-settings',
storage: localStorage,
},
})持久化粒度
只对需要持久化的 Store 开启 persist,如 settings、lock。user、dict、tab 等运行时状态通常不需要持久化。
Schema 版本迁移
settings Store 实现了字段级 schema 版本迁移机制,确保框架升级后不会丢失用户的个性化偏好设置。
工作原理
- 每次持久化数据时,同时记录
schemaVersion - 应用启动时,检测本地存储的
schemaVersion与代码中的版本是否一致 - 若版本不匹配,执行迁移函数,逐字段合并新旧配置
typescript
// stores/settings.migrate.ts
export function migrateSettings(oldData: any, currentVersion: number) {
const { schemaVersion: oldVersion, ...rest } = oldData
if (oldVersion === currentVersion) return oldData
// v1 → v2: 新增字段使用默认值,保留用户已有偏好
if (oldVersion < 2) {
return {
...getDefaultSettings(),
...rest,
schemaVersion: currentVersion,
}
}
return { ...rest, schemaVersion: currentVersion }
}迁移策略
迁移采用字段级合并:新增字段使用默认值,已有字段保留用户设置。这意味着添加新配置项时,用户不会丢失已有偏好。
各 Store 详细说明
userStore
负责用户登录态、用户信息和动态路由管理。
typescript
const userStore = useUserStore()
// 登录
await userStore.login({ username: 'admin', password: '111111' })
// 获取用户信息 + 菜单
await userStore.fetchUserInfo()
// 登出
userStore.logout()dictStore
统一管理数据字典,数据由「字典管理」维护,运行时按 dict_type 动态分组构建。
typescript
const dictStore = useDictStore()
// 获取下拉选项
const statusOptions = dictStore.options('common_status')
// 值转文案
const statusText = dictStore.label('common_status', 1)
// 渲染标签
const statusTag = dictStore.tag('common_status', 1)lockStore
管理锁屏状态,支持空闲超时自动锁定和可选 PIN 解锁。
typescript
const lockStore = useLockStore()
// 锁定屏幕
lockStore.lock()
// 解锁(服务端校验密码)
await lockStore.unlock(password)
// 设置本地 PIN(可选)
await lockStore.setPin(pin)