vue router导航严格按9步执行:触发→beforerouteleave→beforeeach→beforerouteupdate→beforeenter→加载组件→beforerouteenter→beforeresolve→确认→aftereach;三类守卫各守特定关卡,next()是流程开关。

直接看流程图,再对照每个环节对应哪类守卫,比死记分类更牢。关键不是记住“有几种守卫”,而是理解“在跳转的哪个具体时刻,谁先被调用、谁能做什么、谁拿不到 this”。
先搞清导航解析的 9 个真实步骤
每次点击链接或调用 router.push,Vue Router 都会严格按以下顺序执行(不可跳过、不可乱序):
- 导航被触发(URL 开始变化)
- 在将要离开的组件里执行
beforeRouteLeave - 执行全局
beforeEach - 若复用同一组件(比如从 /user/1 切到 /user/2),执行该组件的
beforeRouteUpdate - 在路由配置中检查
beforeEnter(仅当前目标路由有定义才走) - 加载并解析异步组件(如
component: () => import('./Page.vue')) - 在将要进入的组件里执行
beforeRouteEnter - 执行全局
beforeResolve(所有组件和守卫都就绪后,跳转前最后一道闸) - 导航确认 → 触发
afterEach→ DOM 更新 → 执行beforeRouteEnter中传给next的回调
三类守卫各守在哪一关?
把守卫当成“关卡哨兵”,每道关卡只允许特定守卫驻守:
-
全局守卫:守在最外层入口(
beforeEach)、临门一脚前(beforeResolve)、进门后关门(afterEach)。它们不依赖具体页面,适合做登录校验、埋点、权限兜底 -
路由独享守卫(
beforeEnter):只守某一条路的入口,比如 /admin 下的所有子页都必须管理员身份。它在组件加载前运行,但比全局守卫晚一步,且拿不到组件实例 -
组件内守卫:只属于某个 .vue 文件。其中
beforeRouteEnter拿不到this(组件还没造出来),但可用next(vm => {...})延迟到渲染后访问;beforeRouteLeave适合做表单未保存提示;beforeRouteUpdate是唯一能响应“同组件、不同参数”更新的钩子
next() 不是可选项,而是流程开关
几乎所有守卫都必须显式调用 next(),否则导航会卡住不动。它的三种用法决定后续走向:
-
next():放行,进入下一关 -
next(false):撤销本次跳转,浏览器地址栏会回滚到上一页(from 对应的路径) -
next('/login')或next({ name: 'Login' }):中断当前导航,发起新导航 —— 注意避免在beforeEach里无条件跳转,否则可能触发死循环
一个典型场景串起全部流程
用户从 /home 点击跳转到 /profile/123:
- Home 组件先触发
beforeRouteLeave(可弹窗问“确定离开?未保存内容”) - 全局
beforeEach检查 token 是否有效 - 因为 /profile/:id 是动态路由,且 Profile.vue 已加载,跳过
beforeRouteUpdate - 路由配置里写了
beforeEnter?有 → 执行(比如校验用户是否有权查看 ID=123 的资料) - Profile.vue 加载完成 →
beforeRouteEnter被调用(此时this还不存在,但可以请求数据并传给next回调) - 全局
beforeResolve做最终确认(比如等接口返回权限结果) - 跳转完成 →
afterEach更新页面标题或上报 PV










