导航守卫是 Vue Router 的核心控制机制,它像交通信号灯一样管理着路由跳转的每个环节。本文将用通俗易懂的方式讲解 5 类导航守卫,并通过一个完整的电商平台案例演示它们的配合使用。
一、导航守卫类型及执行顺序
1. 全局守卫(控制主干道)
执行顺序:
全局前置守卫
→ 路由独享守卫
→ 组件内离开守卫
→ 全局解析守卫
→ 组件内进入守卫
→ 全局后置钩子
1.1 全局前置守卫(安检入口)
// 所有路由跳转必经之路
router.beforeEach((to, from, next) => {
console.log('【全局安检】开始检查')
next() // 必须放行
})
场景:全站登录验证、权限校验
1.2 全局解析守卫(精确检查)
// 在导航被确认前最后检查
router.beforeResolve((to, from, next) => {
console.log('【最终核查】确认所有条件')
next()
})
场景:异步数据预加载校验
1.3 全局后置钩子(事后记录)
// 导航完成后执行
router.afterEach((to, from) => {
console.log('【行程记录】导航完成')
})
场景:页面访问统计、关闭加载动画
2. 路由独享守卫(VIP通道检查)
// 特定路由的专属守卫
{
path: '/admin',
component: AdminPanel,
beforeEnter: (to, from, next) => {
console.log('【VIP通道】管理员专属检查')
next()
}
}
场景:页面访问权限控制
3. 组件内守卫(私人管家)
// 在组件内部定义
export default {
beforeRouteEnter(to, from, next) {
console.log('【入场准备】组件创建前')
next(vm => {
// 这里可以访问组件实例
})
},
beforeRouteUpdate(to, from, next) {
console.log('【动态更新】路由参数变化')
next()
},
beforeRouteLeave(to, from, next) {
console.log('【离场检查】是否保存修改')
next()
}
}
场景:数据保存提示、动态参数处理
二、实战案例:电商平台路由控制
场景需求
- 未登录用户访问个人中心时跳转登录页
- 管理员页面需要额外权限验证
- 商品编辑页离开时提示保存
- 记录用户页面访问路径
完整代码实现
1. 路由配置
// router.js
const routes = [
{
path: '/',
component: Home
},
{
path: '/login',
component: Login
},
{
path: '/user',
component: UserCenter,
meta: { requiresAuth: true } // 需要登录
},
{
path: '/admin',
component: AdminPanel,
meta: { requiresAdmin: true }, // 需要管理员权限
beforeEnter: (to, from, next) => {
console.log('【路由独享守卫】管理员校验')
next()
}
},
{
path: '/product/:id/edit',
component: ProductEditor
}
]
2. 全局守卫配置
// 全局前置守卫
router.beforeEach((to, from, next) => {
console.log('--- 全局前置守卫开始 ---')
// 检查是否需要登录
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.state.isLogin) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
return
}
}
// 检查管理员权限
if (to.matched.some(record => record.meta.requiresAdmin)) {
if (!store.state.isAdmin) {
next('/403') // 跳转无权限页面
return
}
}
next()
})
// 全局解析守卫
router.beforeResolve((to, from, next) => {
console.log('--- 全局解析守卫 ---')
next()
})
// 全局后置钩子
router.afterEach((to, from) => {
console.log('--- 访问记录 ---', to.path)
analytics.trackPageView(to.path) // 统计访问
})
3. 商品编辑页组件守卫
// ProductEditor.vue
export default {
data() {
return {
isSaved: false
}
},
beforeRouteEnter(to, from, next) {
console.log('进入商品编辑页')
next(vm => {
vm.loadProduct(to.params.id) // 初始化数据
})
},
beforeRouteUpdate(to, from, next) {
console.log('商品ID变化')
this.loadProduct(to.params.id)
next()
},
beforeRouteLeave(to, from, next) {
if (!this.isSaved) {
const answer = confirm('有未保存的修改,确定离开吗?')
if (!answer) return next(false)
}
next()
},
methods: {
async loadProduct(id) {
// 加载商品数据...
}
}
}
三、导航守卫执行流程演示
用户操作:从首页跳转到商品编辑页
1. 【全局前置守卫】开始检查
→ 检查登录状态和权限
2. 【路由独享守卫】管理员校验(本示例不触发)
3. 【组件内离开守卫】beforeRouteLeave
→ 首页组件离开检查
4. 【全局解析守卫】最终确认
5. 【组件内进入守卫】beforeRouteEnter
→ 商品编辑页初始化
6. 【全局后置钩子】记录访问路径
四、next() 方法详解
参数形式 | 行为描述 |
---|---|
next() | 正常放行导航 |
next(false) | 中止当前导航 |
next('/login') | 跳转到指定路径 |
next(error) | 触发路由错误处理 |
特殊技巧:异步操作处理
beforeRouteEnter(to, from, next) {
api.checkAuth().then(() => {
next()
}).catch(() => {
next('/login')
})
}
五、最佳实践建议
-
权限验证分层处理
- 全局守卫:基础登录验证
- 路由守卫:页面级权限控制
- 组件守卫:细粒度数据校验
-
避免在beforeRouteEnter直接操作实例
// 正确方式 next(vm => { vm.loadData() }) // 错误方式 next() this.loadData() // 此时组件未创建
-
合理使用导航中止
// 支付页面离开提示 beforeRouteLeave(to, from, next) { if (this.paymentStatus === 'pending') { return showConfirmModal(next) } next() }
-
性能优化建议
// 路由配置中启用懒加载 { path: '/dashboard', component: () => import('./views/Dashboard.vue') }
通过合理使用导航守卫,开发者可以实现:
- 精准的访问控制
- 流畅的用户体验
- 安全的数据保护
- 完整的访问追踪