vue实现路由守卫
路由守卫的基本概念
路由守卫是Vue Router提供的一种机制,用于在路由跳转前后执行特定的逻辑。它可以用于权限控制、页面访问限制、数据预加载等场景。Vue Router提供了多种路由守卫,包括全局守卫、路由独享守卫和组件内守卫。
全局前置守卫
全局前置守卫通过router.beforeEach注册,会在路由跳转前执行。适合用于权限验证或全局拦截。
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login')
} else {
next()
}
})
全局解析守卫
router.beforeResolve与beforeEach类似,但在导航被确认之前调用,同时在所有组件内守卫和异步路由组件被解析之后调用。
router.beforeResolve((to, from, next) => {
// 确保异步组件已加载
next()
})
全局后置钩子
router.afterEach在路由跳转完成后执行,没有next参数,常用于日志记录或页面标题设置。
router.afterEach((to, from) => {
document.title = to.meta.title || 'Default Title'
})
路由独享守卫
在路由配置中直接定义beforeEnter守卫,只对当前路由生效。
const router = new VueRouter({
routes: [
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
if (!isAdmin()) {
next('/')
} else {
next()
}
}
}
]
})
组件内守卫
在组件内部可以定义以下守卫:
beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave
export default {
beforeRouteEnter(to, from, next) {
// 不能访问组件实例`this`
next(vm => {
// 通过`vm`访问组件实例
})
},
beforeRouteUpdate(to, from, next) {
// 当前路由改变但组件复用时调用
this.name = to.params.name
next()
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件时调用
const answer = confirm('确定要离开吗?')
if (answer) {
next()
} else {
next(false)
}
}
}
守卫执行顺序
- 导航被触发
- 调用失活组件的
beforeRouteLeave - 调用全局的
beforeEach - 在重用的组件里调用
beforeRouteUpdate - 在路由配置里调用
beforeEnter - 解析异步路由组件
- 在被激活的组件里调用
beforeRouteEnter - 调用全局的
beforeResolve - 导航被确认
- 调用全局的
afterEach - 触发DOM更新
- 调用
beforeRouteEnter中传给next的回调函数
常见应用场景
登录验证
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.getters.isLoggedIn) {
next('/login')
} else {
next()
}
} else {
next()
}
})
权限控制
router.beforeEach((to, from, next) => {
const requiredRole = to.meta.role
if (requiredRole && !hasRole(requiredRole)) {
next('/403')
} else {
next()
}
})
页面离开确认
beforeRouteLeave(to, from, next) {
if (this.unsavedChanges) {
if (confirm('有未保存的更改,确定要离开吗?')) {
next()
} else {
next(false)
}
} else {
next()
}
}
注意事项
- 确保始终调用
next(),否则路由跳转会卡住 beforeRouteEnter中无法访问this,因为组件实例尚未创建- 守卫可以是异步函数,支持
async/await - 对于复杂的权限系统,建议将权限逻辑集中管理







