在 Vue.js 应用中,Vue Router 提供了强大的路由守卫功能,用于在路由导航过程中执行特定逻辑,如权限验证、页面标题切换等。以下是路由守卫的详细介绍:
6.13 路由守卫
6.13.1 全局前置守卫
全局前置守卫是在路由切换前执行的钩子函数,可以用于权限控制等。
1. 书写位置
在创建好路由器对象之后,暴露路由器对象之前。
2. 执行时机
在初始化时执行一次,然后在每一次路由切换前都会被调用。
3. 回调函数参数
回调函数有三个参数:to
、from
、next
。
to
:路由对象,表示要跳转到的目标路由。from
:路由对象,表示从哪个路由跳转而来。next
:函数,调用该函数表示放行,可以继续向下执行。
4. 使用示例
// 创建路由器对象
const router = new VueRouter({
routes: [
{
path: '/subject1',
component: subject1,
},
{
path: '/subject2',
component: subject2,
meta: {
isAuth: true }, // 需要鉴权的路由
},
],
});
// 全局前置守卫
router.beforeEach((to, from, next) => {
// 判断是否需要鉴权
if (to.meta.isAuth) {
// 验证用户权限
if (localStorage.getItem('token')) {
next(); // 放行
} else {
alert('对不起,你没有权限访问该页面');
next('/login'); // 重定向到登录页面
}
} else {
next(); // 不需要鉴权,直接放行
}
});
6.13.2 全局解析守卫
全局解析守卫在全局前置守卫之后执行,用于在导航被确认之前、所有组件内守卫和异步路由组件被解析之后进行操作。
router.beforeResolve((to, from) => {
if (to.meta.requiresCamera) {
try {
await askForCameraPermission();
} catch (error) {
if (error instanceof NotAllowedError) {
// 处理错误,取消导航
return false;
} else {
// 意料之外的错误,取消导航并传给全局处理器
throw error;
}
}
}
});
6.13.3 全局后置守卫
全局后置守卫是在路由切换完成后执行的钩子函数,可以用于页面标题切换等。
// 全局后置守卫
router.afterEach((to, from) => {
// 切换页面标题
document.title = to.meta.title || '欢迎使用';
});
6.13.4 路由独享的守卫
可以在特定路由配置中定义 beforeEnter
守卫,用于在进入该路由前执行逻辑。
const routes = [
{
path: '/subject2',
component: subject2,
beforeEnter: (to, from, next) => {
// 验证用户权限
if (localStorage.getItem('token')) {
next(); // 放行
} else {
alert('对不起,你没有权限访问该页面');
next('/login'); // 重定向到登录页面
}
},
},
];
6.13.5 组件内的守卫
在路由组件内定义守卫,用于在进入、更新或离开路由组件时执行逻辑。
export default {
name: 'subject2',
beforeRouteEnter(to, from, next) {
console.log(`进入路由组件之前: ${
to.meta.title}`);
next();
},
beforeRouteUpdate(to, from) {
console.log(`路由更新: ${
to.meta.title}`);
},
beforeRouteLeave(to, from, next) {
console.log(`离开路由组件之前: ${
from.meta.title}`);
next();
},
};
6.13.6 完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
通过合理使用路由守卫,可以有效地控制路由的访问权限、优化用户体验以及实现一些特定的业务逻辑。