Vue导航守卫学习 📅 2026/7/7 5:28:58 Vue 导航守卫Navigation Guards学习文档适用版本Vue Router 3.xVue 2/ Vue Router 4.xVue 3语法略有差异一、什么是导航守卫导航守卫是 Vue Router 提供的路由跳转过程中的钩子函数主要用于登录鉴权 / 权限校验页面标题document.title设置数据预取阻止或重定向非法跳转埋点、离开确认等它们会在路由发生变化时按固定顺序依次触发。二、三大分类1. 全局守卫定义在router实例上constrouternewVueRouter({routes})// ① 前置守卫最常用登录校验主战场router.beforeEach((to,from,next){// to: 目标路由// from: 离开的路由// next: 放行函数必须调用否则路由停滞next()})// ② 解析守卫在组件内守卫和异步路由组件被解析之后触发router.beforeResolve((to,from,next){next()})// ③ 后置钩子导航已完成无 next常用于埋点、滚动复位router.afterEach((to,from){window.scrollTo(0,0)})2. 路由独享守卫定义在路由配置里{path:/settlement,component:Settlement,beforeEnter:(to,from,next){// 仅对当前路由生效next()}}3. 组件内守卫定义在组件选项里exportdefault{// ⚠️ 此时组件实例尚未创建拿不到 thisbeforeRouteEnter(to,from,next){next(vm{// 通过回调访问实例唯一的特例})},// 当前路由改变、但组件复用时触发如 /user/1 → /user/2beforeRouteUpdate(to,from,next){this.fetchData(to.params.id)next()},// 离开时触发this 可用常用于「未保存提示」beforeRouteLeave(to,from,next){if(this.formDirty!confirm(有未保存内容确定离开)){next(false)// 取消导航}else{next()}}}三、next()的用法调用方式含义next()放行继续跳转到tonext(false)中断回到当前页fromnext(/login)重定向到指定路径next(new Error(...))触发router.onErrornext(vm {...})仅beforeRouteEnter可用Vue Router 4 (Vue 3)中改为return语义return true / false / /login不再强制next。四、完整的导航解析顺序重点一次跳转会按以下顺序触发1. 导航被触发 2. 在失活组件里调用 beforeRouteLeave 3. 调用全局 beforeEach 4. 在重用组件里调用 beforeRouteUpdate 5. 调用路由配置里的 beforeEnter 6. 解析异步路由组件 7. 在被激活组件里调用 beforeRouteEnter 8. 调用全局 beforeResolve 9. 导航被确认 10. 调用全局 afterEach 11. 触发 DOM 更新 12. 调用 beforeRouteEnter 中 next 传入的回调记忆口诀「离开 → 全局前置 → 复用更新 → 独享 → 解析组件 → 进入 → 全局解析 → 确认 → 全局后置」。五、实战登录鉴权典型场景使用token标记需要登录的路由可在router/index.js这样实现import{getToken}from/utils/auth// 从 Cookie 读取 USER_TOKENconstWHITE_LIST[/login,/register,/403]router.beforeEach((to,from,next){// 1. 设置页面标题document.titleto.meta.tabTitle||资环链金智慧平台consthasTokengetToken()if(hasToken){if(to.path/login){next({path:/})// 已登录则拦截登录页}else{next()// 正常放行}}else{// 白名单放行其余统一跳登录并带上 redirectWHITE_LIST.includes(to.path)?next():next(/login?redirect${encodeURIComponent(to.fullPath)})}})六、常见坑位忘记调用next()→ 页面卡住、白屏最经典的错误。死循环beforeEach里重定向到自己如已登录又next(/login)需加条件分支。异步校验鉴权接口需await后再next()否则拿不到结果就放行了。beforeRouteEnter拿不到this必须用next(vm {...})回调。组件复用不触发created参数变化/detail/1→/detail/2只触发beforeRouteUpdate需在此重新请求数据或在router-view :key$route.fullPath强制重建。七、速查表守卫位置是否能取消跳转典型用途beforeEach全局✅登录/权限校验beforeResolve全局✅数据预加载完成后处理afterEach全局❌标题、滚动、埋点beforeEnter路由✅单路由鉴权beforeRouteEnter组件✅进入前数据校验beforeRouteUpdate组件✅动态参数变化beforeRouteLeave组件✅离开确认/防误操作八、Vue 3 补充Composition API在script setup中可用专用钩子script setup import { onBeforeRouteLeave, onBeforeRouteUpdate } from vue-router onBeforeRouteLeave((to, from) { const answer window.confirm(确定离开吗) if (!answer) return false // 取消导航 }) onBeforeRouteUpdate((to, from) { // 路由参数变化时触发 fetchData(to.params.id) }) /script注意Vue 3 中没有onBeforeRouteEnter进入前逻辑需通过beforeEnter路由独享守卫或在组件setup中直接处理。