核心是守卫只调用 Pinia store 的 actions/getters 做鉴权决策,不直接读 localStorage、不手动改状态、不发请求;权限获取、存储、动态路由注册等均封装在 store 中,确保状态统一、可追踪、初始化同步。

Vue 路由守卫结合 Pinia 验证用户权限,核心是把权限判断逻辑从守卫里“抽出来”,交给 Pinia store 统一管理。守卫只负责调用 store 的方法或 getter 做决策,不直接读 localStorage、不手动改角色数组、也不在守卫里发请求拉权限——这些都应封装进 store 的 action 或 getter 中。
用 store 实例读取最新权限状态
在守卫中必须通过 useUserStore() 获取 store 实例,而不是缓存旧值或读取本地存储:
- 调用 userStore.getRoles() 或 userStore.permissions(推荐封装为 getter)获取当前角色/权限列表
- 避免直接访问 userStore.$state.roles,尤其在异步加载未完成时可能为空或过期
- 若权限需接口获取(如登录后请求
/api/user/permissions),先检查 userStore.isPermissionsLoaded,未加载完可暂停导航(next(false))或显示 loading 提示
在守卫中做鉴权决策,不是赋值操作
守卫的职责是“放行、重定向、拦截”,不是“设置权限”:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
- 检查 to.meta.requiresAuth:未登录(
!userStore.isLoggedIn)则跳转登录页,并用to.fullPath缓存目标地址 - 检查 to.meta.roles 或 to.meta.permissions:用
userStore.hasRole('admin')或userStore.hasPermission('user:delete')判断,不匹配则跳转 403 页面 - 对敏感路由(如
/admin/logs),可在守卫中额外调用细粒度校验,比如userStore.canAccessRoute(to)
需要时触发权限同步与动态路由注册
权限变化常发生在守卫执行过程中,store 应提供可被守卫调用的响应式能力:
立即学习“前端免费学习笔记(深入)”;
- 若已登录但 userStore.roles.length === 0,说明权限尚未加载,可调用 userStore.fetchPermissions() 并 await 完成后再
next() - 权限加载成功后,若使用动态路由,调用 userStore.addDynamicRoutes(routes),内部执行
router.addRoute()注册对应页面路由 - 登出或 token 失效时,在守卫中调用 userStore.logout(),该 action 应清空状态、移除持久化数据,并重定向
确保初始化与持久化同步,避免状态滞后
守卫执行快,但 store 初始化可能有延迟,必须提前兜底:
- store 创建时启用 pinia-plugin-persistedstate,从 localStorage 恢复
token和roles,避免首次进入守卫时状态为空 - 登录 action(
login())中统一处理:请求用户信息 → 解析角色/权限 → 存入 store → 触发路由更新,不分散在多个地方写赋值逻辑 - 刷新页面后,store 自动恢复,守卫能立即拿到有效状态,无需二次登录或白屏等待


















