阿杰,我帮你整理一份 Vue 路由守卫(Navigation Guards)详解,包括类型、使用方式、示例和注意事项。这里主要以 Vue 3 + Vue Router 4 为例。
一、概念
- 路由守卫:在路由跳转过程中触发的钩子函数,用于控制访问权限、路由重定向、数据加载等操作。
- 核心作用:
- 判断用户是否有权限访问页面
- 跳转前/跳转后执行逻辑(如请求数据、显示 Loading)
- 防止非法路由访问
二、路由守卫分类
类型 | 调用时机 | 作用范围 |
---|---|---|
全局前置守卫 beforeEach | 路由跳转前 | 所有路由 |
全局解析守卫 beforeResolve | 路由解析完成,组件渲染前 | 所有路由 |
全局后置守卫 afterEach | 路由跳转完成后 | 所有路由(不能阻止跳转) |
路由独享守卫 beforeEnter | 路由配置中 | 单个路由 |
组件内守卫 beforeRouteEnter / beforeRouteUpdate / beforeRouteLeave | 组件内 | 组件级控制 |
三、全局守卫示例
1. 全局前置守卫 beforeEach
import router from './router';
router.beforeEach((to, from, next) => {
// 判断是否需要登录
if (to.meta.requiresAuth) {
const isLogin = !!localStorage.getItem('token');
if (!isLogin) {
next({ name: 'Login' }); // 重定向到登录页
} else {
next(); // 放行
}
} else {
next();
}
});
2. 全局解析守卫 beforeResolve
router.beforeResolve((to, from, next) => {
console.log('路由解析完成,组件渲染前');
next();
});
3. 全局后置守卫 afterEach
router.afterEach((to, from) => {
console.log(`从 ${from.fullPath} 到 ${to.fullPath}`);
// 设置页面标题
document.title = to.meta.title || 'Vue App';
});
四、路由独享守卫 beforeEnter
const routes = [
{
path: '/admin',
name: 'Admin',
component: Admin,
beforeEnter: (to, from, next) => {
const isAdmin = localStorage.getItem('role') === 'admin';
if (isAdmin) next();
else next({ name: 'Home' });
}
}
];
五、组件内守卫
1. beforeRouteEnter
- 在路由进入前调用,无法直接访问
this
,但可以通过回调获取组件实例。
export default {
name: 'Profile',
beforeRouteEnter(to, from, next) {
console.log('进入 Profile 页面前');
next(vm => {
// vm 是组件实例
vm.fetchUserData();
});
},
methods: {
fetchUserData() { console.log('获取用户数据'); }
}
}
2. beforeRouteUpdate
- 当前路由改变,但组件复用时调用。
beforeRouteUpdate(to, from, next) {
this.fetchUserData();
next();
}
3. beforeRouteLeave
- 离开当前路由前调用,可阻止离开。
beforeRouteLeave(to, from, next) {
if (this.hasUnsavedChanges) {
const answer = window.confirm('你有未保存的数据,确定离开吗?');
if (answer) next();
else next(false);
} else {
next();
}
}
六、常用技巧
- 结合 meta 字段控制权限
{
path: '/dashboard',
meta: { requiresAuth: true }
}
- 处理异步权限或数据请求
router.beforeEach(async (to, from, next) => {
const user = await getUserInfo();
if (to.meta.requiresAdmin && !user.isAdmin) next('/');
else next();
});
- 防止重复跳转错误(Vue Router 4)
const originalPush = router.push;
router.push = function push(location) {
return originalPush.call(this, location).catch(err => err);
}
七、总结
- 全局守卫:控制全局访问与权限
- 路由独享守卫:针对单个路由的权限控制
- 组件内守卫:处理组件级生命周期逻辑,如数据获取、确认离开
路由守卫是 前端权限控制、数据加载和页面状态管理的核心工具,在大型 SPA 项目中必不可少。
发表回复