# 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 |