Vue路由导航守卫详解:控制与实战应用
Vue 路由导航控制与守卫详解
导航守卫是 Vue Router 中控制路由跳转的核心机制,它允许开发者在路由切换的不同阶段插入自定义逻辑。本文将深入解析各类导航守卫及其应用场景。
一、导航守卫分类
1. 全局守卫
全局守卫作用于所有路由跳转:
const router = createRouter({ ... })
// 前置守卫
router.beforeEach((to, from, next) => {
// 在路由跳转前执行
console.log(`Navigating from ${from.path} to ${to.path}`)
next() // 必须调用 next() 继续导航
})
// 后置守卫
router.afterEach((to, from) => {
// 在路由跳转后执行,没有 next 参数
logPageView(to.fullPath)
})
实践建议:
- 全局前置守卫适合做权限控制、登录验证等全局性逻辑
- 后置守卫适合做页面统计、埋点等不需要阻塞导航的操作
2. 路由独享守卫
在路由配置中直接定义的守卫:
const routes = [
{
path: '/admin',
component: AdminPanel,
beforeEnter: (to, from, next) => {
if (!isAdmin()) {
next('/login') // 重定向
} else {
next()
}
}
}
]
实践建议:
- 适合特定路由的权限校验
- 比全局守卫更早执行
3. 组件内守卫
在组件内部定义的守卫:
const UserDetails = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this`
next(vm => {
// 通过 `vm` 访问组件实例
})
},
beforeRouteUpdate(to, from, next) {
// 当前路由改变但组件被复用时调用
// 可以访问 `this`
this.userData = fetchUser(to.params.id)
next()
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
if (this.hasUnsavedChanges) {
if (confirm('有未保存的更改,确定离开?')) {
next()
} else {
next(false)
}
} else {
next()
}
}
}
执行顺序:
二、导航行为控制
1. 取消导航
next(false) // 中断当前导航
2. 重定向
next('/login') // 重定向到登录页
next({ path: '/login', query: { redirect: to.fullPath } }) // 带参数重定向
3. 错误处理
next(new Error('Network Error')) // 触发路由错误回调
router.onError(error => {
console.error('路由错误:', error)
showErrorPage()
})
实践建议:
- 在全局守卫中统一处理未捕获的导航错误
- 对于权限类错误,可以提供友好的重定向而不是直接报错
三、常见应用场景
1. 登录验证
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isLoggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
})
2. 页面标题管理
router.afterEach((to) => {
document.title = to.meta.title || '默认标题'
})
3. 滚动行为控制
const router = createRouter({
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else if (to.hash) {
return { el: to.hash }
} else {
return { top: 0 }
}
}
})
四、性能与调试建议
- 避免过度使用全局守卫:全局守卫会在每次导航时执行,复杂逻辑可能影响性能
守卫中的异步操作:
beforeRouteEnter(to, from, next) { fetchData().then(data => { next(vm => vm.setData(data)) }) }
调试技巧:
router.beforeEach((to, from, next) => { console.log('[路由跳转]', from.path, '->', to.path) next() })
导航守卫是 Vue Router 强大功能的体现,合理使用可以构建出既安全又用户体验良好的应用。根据具体场景选择合适的守卫类型,并注意保持守卫逻辑的简洁和高效。
评论已关闭