路由守卫分类
1. 全局守卫
beforeEach
:导航前触发,常用于全局权限校验(如登录状态检测)beforeResolve
:导航确认前触发,适用于需要等待异步组件或数据解析的场景afterEach
:导航完成后触发,用于日志记录或页面统计
2. 路由独享守卫
beforeEnter
:在特定路由配置中定义,仅对该路由生效(如动态权限路由)
{
name:'xinwen',
path:'news',
component:News,
meta:{isAuth:true,title:'新闻'},
beforeEnter: (to, from, next) => {
console.log('独享路由守卫',to,from)
if(to.meta.isAuth){ //判断是否需要鉴权
if(localStorage.getItem('school')==='atguigu'){
next()
}else{
alert('学校名不对,无权限查看!')
}
}else{
next()
}
}
}
3. 组件内路由
beforeRouteEnter
:组件实例化前触发,无法访问this
,但可通过next(vm => {})
访问实例beforeRouteUpdate
:当前路由参数变化时触发(如动态路径/user/:id
切换时复用组件)beforeRouteLeave
:离开当前路由前触发,用于数据保存或离开确认弹窗
导航解析流程
- 触发导航(如调用
router.push
或点击<router-link>
) - 调用当前组件
beforeRouteLeave
守卫 - 执行全局
beforeEach
守卫 - 调用目标路由的
beforeEnter
守卫 - 解析异步路由组件
- 执行目标组件的
beforeRouteEnter
守卫 - 触发全局
beforeResolve
守卫 - 完成导航并触发
afterEach
- 调用
beforeRouteEnter
中通过next
传递的回调函数
场景案例
1. 身份验证,全局beforeEach
拦截未登录用户访问受限页面,并重定向至登录页
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated) next('/login')
else next()
})
2. 动态参数处理,beforeRouteUpdate
监听路由参数变化并重新加载数据
beforeRouteUpdate(to, from, next) {
this.fetchData(to.params.id)
next()
}
3. 离开页面确认,beforeRouteLeave
阻止用户意外离开未保存表单的页面
beforeRouteLeave(to, from, next) {
if (this.unsavedChanges) {
if (confirm('数据未保存,确定离开?')) next()
else next(false)
} else next()
}
注意事项
next()
方法必须调用,否则导航会处于挂起状态,导致页面无响应- 异步组件处理,在
beforeRouteEnter
中需通过回调访问组件实例,避免直接操作未初始化的组件 - 性能优化,避免在全局守卫中频繁执行耗时操作,可通过路由元信息(
meta
字段)精细化控制逻辑