Vue Router 路由守卫钩子详解
🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
文章目录
- 一、引言
- 二、路由守卫的钩子函数
- (一)全局守卫
- (二)路由独享守卫
- (三)组件内守卫
- 三、路由守卫的执行顺序
- 四、使用场景
- (一)全局前置守卫:权限验证
- (二)全局后置守卫:页面加载提示
- (三)路由独享守卫:数据预加载
- (四)组件内守卫:表单数据验证
- 五、总结
Vue Router 提供了多种路由守卫钩子,这些钩子函数允许开发者在路由跳转的不同阶段插入自定义逻辑。合理使用这些钩子可以实现权限验证、数据预加载、页面跳转确认等功能,从而提升用户体验和应用的安全性
。本文将详细介绍 Vue Router 路由守卫的钩子函数及其执行时机。
一、引言
在单页应用(SPA)中,路由跳转是用户与应用交互的核心部分。Vue Router 提供了丰富的路由守卫机制,允许开发者在路由跳转的不同阶段插入自定义逻辑。这些路由守卫可以用于执行权限检查、数据预加载、页面跳转确认等操作,从而增强应用的用户体验和安全性。
二、路由守卫的钩子函数
Vue Router 提供了多种路由守卫钩子函数,这些钩子函数可以在路由跳转的不同阶段被调用。根据调用时机和作用范围,路由守卫可以分为全局守卫、路由独享守卫和组件内守卫。
(一)全局守卫
全局守卫是在路由跳转的全局范围内生效的钩子函数。Vue Router 提供了以下几种全局守卫:
-
全局前置守卫(
beforeEach
)- 执行时机:在路由跳转之前被调用。
- 用途:全局权限验证、页面加载提示等。
- 参数:
to
(即将进入的路由对象)、from
(即将离开的路由对象)、next
(一个回调函数,用于控制路由跳转是否继续)。
const router = new VueRouter({ ... });router.beforeEach((to, from, next) => {console.log('全局前置守卫', to, from);next(); // 必须调用 next(),否则路由跳转不会继续 });
-
全局解析守卫(
beforeResolve
)- 执行时机:在路由跳转之前被调用,但在全局前置守卫之后。
- 用途:数据预加载、页面加载提示等。
- 参数:
to
、from
和next
。
router.beforeResolve((to, from, next) => {console.log('全局解析守卫', to, from);next(); });
-
全局后置守卫(
afterEach
)- 执行时机:在路由跳转完成后被调用。
- 用途:页面加载完成后的操作,如关闭加载提示、记录页面访问日志等。
- 参数:
to
和from
。
router.afterEach((to, from) => {console.log('全局后置守卫', to, from); });
(二)路由独享守卫
路由独享守卫是定义在路由配置中的钩子函数,仅对特定的路由生效。它通常用于路由级别的权限验证或数据预加载。
- 执行时机:在路由跳转之前被调用。
- 用途:路由级别的权限验证、数据预加载等。
- 参数:
to
、from
和next
。
const routes = [{path: '/user/:id',component: User,beforeEnter: (to, from, next) => {console.log('路由独享守卫', to, from);next();}}
];
(三)组件内守卫
组件内守卫是定义在组件内部的钩子函数,仅对当前组件生效。它通常用于组件级别的权限验证或数据预加载。
-
beforeRouteEnter
- 执行时机:在路由进入组件之前被调用。
- 用途:组件级别的权限验证、数据预加载等。
- 参数:
to
、from
和next
。 - 注意:无法直接访问
this
,因为此时组件实例尚未创建。
export default {beforeRouteEnter(to, from, next) {console.log('组件内前置守卫', to, from);next();} };
-
beforeRouteUpdate
- 执行时机:在路由更新组件时被调用(例如,动态路由参数变化时)。
- 用途:组件级别的数据更新、权限验证等。
- 参数:
to
、from
和next
。 - 注意:可以访问
this
。
export default {beforeRouteUpdate(to, from, next) {console.log('组件内更新守卫', to, from);next();} };
-
beforeRouteLeave
- 执行时机:在路由离开组件之前被调用。
- 用途:组件级别的权限验证、数据保存提示等。
- 参数:
to
、from
和next
。 - 注意:可以访问
this
。
export default {beforeRouteLeave(to, from, next) {console.log('组件内离开守卫', to, from);next();} };
三、路由守卫的执行顺序
在路由跳转过程中,Vue Router 会按照以下顺序执行路由守卫:
- 全局前置守卫(
beforeEach
) - 路由独享守卫(
beforeEnter
) - 组件内前置守卫(
beforeRouteEnter
) - 全局解析守卫(
beforeResolve
) - 组件内更新守卫(
beforeRouteUpdate
) - 全局后置守卫(
afterEach
) - 组件内离开守卫(
beforeRouteLeave
)
四、使用场景
(一)全局前置守卫:权限验证
全局前置守卫常用于全局权限验证。例如,检查用户是否登录,如果没有登录,则重定向到登录页面。
router.beforeEach((to, from, next) => {if (to.matched.some(record => record.meta.requiresAuth)) {if (!isAuthenticated()) {next({ path: '/login' });} else {next();}} else {next();}
});
(二)全局后置守卫:页面加载提示
全局后置守卫常用于页面加载完成后的操作,例如关闭加载提示。
router.afterEach((to, from) => {console.log('页面加载完成');// 关闭加载提示hideLoadingIndicator();
});
(三)路由独享守卫:数据预加载
路由独享守卫常用于特定路由的数据预加载。例如,在进入用户详情页面时,预加载用户数据。
const routes = [{path: '/user/:id',component: User,beforeEnter: (to, from, next) => {fetchUserData(to.params.id).then(() => {next();}).catch(() => {next({ path: '/error' });});}}
];
(四)组件内守卫:表单数据验证
组件内守卫常用于组件级别的操作,例如在离开表单页面时验证数据是否已保存。
export default {data() {return {form: {name: '',email: ''}};},beforeRouteLeave(to, from, next) {if (this.isFormDirty()) {const answer = window.confirm('您有未保存的更改,确定要离开吗?');if (answer) {next();} else {next(false);}} else {next();}},methods: {isFormDirty() {return this.form.name || this.form.email;}}
};
五、总结
Vue Router 的路由守卫提供了强大的功能,允许开发者在路由跳转的不同阶段插入自定义逻辑。通过合理使用全局守卫、路由独享守卫和组件内守卫,可以实现权限验证、数据预加载、页面加载提示、表单数据验证等多种功能,从而提升应用的用户体验和安全性。在实际开发中,应根据具体需求选择合适的路由守卫,并确保逻辑清晰、易于维护。