82 lines
2.9 KiB
Markdown
82 lines
2.9 KiB
Markdown
# 9.6 状态管理(Pinia)
|
||
|
||
:::tip 概述
|
||
状态管理用 Pinia,modules 七个状态域:user(登录身份)、asyncRoute(动态路由)、tabsView(标签页)、designSetting/projectSetting(界面设置)、lockscreen(锁屏)、ossConfig(存储配置)。本节说明各域职责与关键状态。
|
||
:::
|
||
|
||
## Store 模块清单(store/modules/)
|
||
|
||
| 模块 | 职责 | 关键状态/动作 |
|
||
|------|------|-------------|
|
||
| user.ts | 登录与身份 | token(ACCESS_TOKEN)、用户信息、Login/GetInfo/LogOut |
|
||
| asyncRoute.ts | 动态路由 | 菜单树、generateRoutes、isDynamicAddedRoute |
|
||
| tabsView.ts | 标签页 | 多标签缓存、visitedTabs、delCachedTab |
|
||
| designSetting.ts | 设计设置 | 主题色、水印、灰度/色弱模式 |
|
||
| projectSetting.ts | 项目设置 | 布局模式、标签页开关、面包屑等 |
|
||
| lockscreen.ts | 锁屏 | 锁定状态、解锁 |
|
||
| ossConfig.ts | 存储配置 | OSS 相关配置状态 |
|
||
|
||
辅助文件:`mutation-types.ts`(ACCESS_TOKEN/FIRST_ROUTE 等存储键常量)、`index.ts`(createPinia)、`types.ts`、`plugins/`(持久化插件)。
|
||
|
||
## user 模块(核心)
|
||
|
||
```text
|
||
状态:
|
||
token 从 storage.get(ACCESS_TOKEN) 恢复(刷新不丢)
|
||
userInfo getUser 接口数据(头像/名称/permissions…)
|
||
|
||
动作:
|
||
Login 登录 → data.access_token 存 storage + store
|
||
GetInfo 调 /api/index/getUser → 权限/角色注入
|
||
LogOut 调 /api/logout → 清 token/存储 → 跳登录
|
||
|
||
关键:登录响应读 data.access_token(下划线字段)
|
||
```
|
||
|
||
## asyncRoute 模块(动态路由)
|
||
|
||
```text
|
||
generateRoutes(userInfo):
|
||
调 /api/index/getMenus → 菜单树
|
||
→ generator-routers 转换为路由记录(component 动态 import)
|
||
→ 常量路由 + 动态路由合并 → 返回
|
||
|
||
isDynamicAddedRoute:守卫判断"是否已注入动态路由"的标志
|
||
```
|
||
|
||
## 令牌存储(mutation-types + Storage)
|
||
|
||
```text
|
||
ACCESS_TOKEN = "ACCESS_TOKEN" storage 封装(utils/Storage.ts)
|
||
登录写入 → 守卫读取 → http 拦截器注入 Authorization
|
||
登出/401 清除
|
||
```
|
||
|
||
## 使用模式
|
||
|
||
```ts
|
||
// 组件内获取状态
|
||
const userStore = useUserStore();
|
||
const avatar = userStore.userInfo?.avatar;
|
||
|
||
// 跨组件动作
|
||
const { logOut } = useUserStoreWidthOut(); // store 外引用(store/modules 导出)
|
||
```
|
||
|
||
## 持久化策略
|
||
|
||
```text
|
||
token:localStorage 持久化(刷新不丢)
|
||
用户信息/菜单:内存态(刷新重新 GetInfo + generateRoutes)
|
||
界面设置:持久化(designSetting/projectSetting 经插件)
|
||
```
|
||
|
||
## 排障
|
||
|
||
| 症状 | 原因 |
|
||
|------|------|
|
||
| 刷新后回登录页 | ACCESS_TOKEN 未持久化或被清;查 storage 与守卫 |
|
||
| 权限按钮不更新 | GetInfo 缓存旧 permissions;重新登录或刷新用户信息 |
|
||
| 标签页缓存失效 | tabsView cachedTabs 与 keep-alive name 不匹配 |
|
||
| store 类型报错 | types.ts 与模块状态不一致;跑 type:check |
|