Vue 3登录拦截需先搭骨架再填逻辑:1.用createRouter+createWebHistory建路由并标记requiresAuth;2.beforeEach守卫依Pinia状态判断,未登录跳/login并带redirect参数;3.Pinia同步token防刷新丢失;4.处理动态路由、401响应和next()漏调等边界问题。

Vue 3 项目初始化阶段配置路由守卫实现登录拦截,核心是“先搭骨架、再填逻辑”,重点在于守卫触发时机、状态判断依据和跳转控制闭环。不需要一上来就写复杂权限,先把「未登录→跳登录」「已登录→放行/重定向」跑通即可。
1. 创建路由实例并启用 history 模式
使用 createRouter + createWebHistory 是 Vue Router 4 的标准写法,必须显式声明 history,否则报错:
- 避免用 hash 模式(
createWebHashHistory),除非有特殊部署限制;history 模式更符合后台系统语义,也便于后续服务端配合 - 路由表里给需要鉴权的页面加
meta: { requiresAuth: true }标记,比如首页、用户管理页等 - 白名单路径(如
/login、/404)不设该标记,方便守卫统一识别
2. 在 beforeEach 中实现基础拦截逻辑
全局前置守卫是登录拦截的主战场,关键点在于:判断依据要可靠、跳转目标要明确、避免死循环:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
- 从 Pinia store(如
useUserStore())读取token或isLoggedIn状态,而不是只查 localStorage —— 因为 token 可能已过期,需结合后端响应码(如 401)二次校验 - 已登录时访问
/login,应主动next('/')或next({ name: 'Home' }),防止用户手动输入登录页绕过首页 - 未登录且目标不是白名单页,跳转时带上
redirect参数,例如next(`/login?redirect=${to.fullPath}`),登录成功后可精准返回
3. 配合 Pinia 实现状态联动
路由守卫本身不存状态,它依赖外部状态源。Pinia 必须提前完成 token 持久化配置:
立即学习“前端免费学习笔记(深入)”;
- store 初始化时,从
localStorage或sessionStorage同步 token,确保页面刷新后状态不丢失 - 提供
setToken(token)和clearToken()方法,登录成功后调用前者,登出或 401 响应后调用后者 - 守卫中通过
userStore.isLoggedIn计算属性判断,比每次读 localStorage 更安全、更易测试
4. 补充细节防踩坑
看似简单的拦截,实际容易在边界场景翻车:
-
动态路由未注册前访问:如果菜单是异步拉取+
router.addRoute()注入的,守卫里直接next()可能跳到空白页。建议首次进入时先await permissionStore.buildRoutesAction()再放行 -
401 响应未处理:Axios 响应拦截器中检测到 401,应自动调用
userStore.clearToken()并router.push('/login'),否则 token 还在内存里,守卫会误判为已登录 -
导航被取消仍执行 next():每个分支都必须调用
next()(包括next(false)或next('/login')),漏写会导致整个路由卡死


















