Vue Router 钩子函数与组件生命周期执行顺序详解
Vue Router 钩子函数与组件生命周期执行顺序详解
一、Vue Router 核心钩子函数分类
Vue Router 提供了三类路由守卫(钩子函数),用于控制导航流程:
1. 全局守卫
router.beforeEach(to, from, next)
:全局前置守卫,导航触发前全局执行(所有路由跳转都会触发)router.beforeResolve(to, from, next)
:全局解析守卫,所有组件内守卫和异步路由组件加载完成后执行router.afterEach(to, from)
:全局后置钩子,导航完成后执行(无 next 参数,不影响导航流程)
2. 路由独享守卫
beforeEnter(to, from, next)
:配置在路由对象中的守卫,仅当进入该路由时触发(优先级高于组件内守卫)
3. 组件内守卫
beforeRouteEnter(to, from, next)
:进入当前组件对应路由前触发(此时组件实例未创建,无法访问this
)beforeRouteUpdate(to, from, next)
:当前组件路由参数变化时触发(如从/user/123
跳转到/user/456
)beforeRouteLeave(to, from, next)
:离开当前组件对应路由前触发(常用于阻止用户未保存时离开)
二、Vue 组件生命周期钩子(关键阶段)
组件生命周期与路由导航强相关的钩子如下(按执行顺序):
beforeCreate
:实例初始化前(数据观测和事件配置之前)created
:实例初始化完成(数据观测和事件配置完成,未挂载 DOM)beforeMount
:挂载开始前($el
为虚拟 DOM)mounted
:挂载完成(真实 DOM 渲染完毕)beforeUpdate
:数据更新前(虚拟 DOM 重新渲染前)updated
:数据更新后(虚拟 DOM 重新渲染完成)beforeUnmount
:实例卸载前(清理定时器、事件监听器等)unmounted
:实例卸载完成(所有子组件已卸载)
三、完整执行顺序流程(场景化说明)
场景 1:首次进入新路由(从 A 路由跳转到 B 路由,B 组件未加载过)
执行顺序:
- 全局前置守卫
router.beforeEach
(导航开始) - 路由独享守卫
B路由.beforeEnter
(若配置) - 组件内守卫
B组件.beforeRouteEnter
(进入 B 前) - 解析守卫
router.beforeResolve
(B 组件及依赖加载完成) - 全局后置钩子
router.afterEach
(导航完成) - B 组件生命周期:
beforeCreate
→created
→beforeMount
→mounted
(组件挂载)
场景 2:路由更新(当前组件不变,参数变化,如 /user/123
→ /user/456
)
执行顺序:
- 全局前置守卫
router.beforeEach
(导航开始) - 路由独享守卫
当前路由.beforeEnter
(若配置) - 组件内守卫
当前组件.beforeRouteUpdate
(参数变化时) - 解析守卫
router.beforeResolve
(确认导航) - 全局后置钩子
router.afterEach
(导航完成) - 组件生命周期:
beforeUpdate
→updated
(组件更新)
场景 3:离开当前路由(从 B 路由跳转到 C 路由)
执行顺序:
- 组件内守卫
B组件.beforeRouteLeave
(离开 B 前,常用于阻止未保存操作) - 全局前置守卫
router.beforeEach
(导航开始) - C 路由相关守卫(重复场景 1 流程)
- B 组件生命周期:
beforeUnmount
→unmounted
(B 组件卸载)
四、总结表格
阶段 | 钩子函数/生命周期 | 触发时机 |
---|---|---|
导航开始 | router.beforeEach | 所有路由跳转前 |
进入目标路由前 | 目标路由 beforeEnter | 仅目标路由配置时触发 |
组件加载前 | 目标组件 beforeRouteEnter | 组件实例创建前 |
依赖解析完成 | router.beforeResolve | 所有组件和异步资源加载完成后 |
导航完成 | router.afterEach | 路由跳转成功后 |
组件挂载 | beforeCreate → mounted | 首次进入路由时组件初始化 |
路由参数更新 | 组件 beforeRouteUpdate | 同组件路由参数变化时 |
组件更新 | beforeUpdate → updated | 数据变化导致重新渲染时 |
离开当前路由 | 当前组件 beforeRouteLeave | 离开前(可阻止导航) |
组件卸载 | beforeUnmount → unmounted | 路由跳转后原组件销毁时 |