在Vue 3中,路由守卫是一种控制和管理路由跳转的机制。它允许你在执行导航前后进行一些逻辑处理,比如权限验证、数据预取等,从而增强应用的安全性和效率。路由守卫分为几种不同的类型,每种类型的守卫都有其特定的应用场景。
其实路由守卫跟生命周期的钩子函数有相似之处,都是在特定的时机执行特定函数 , 不过路由守卫主要关注的是路由级别的导航控制,而生命周期钩子则更侧重于组件自身的状态变化。
全局守卫
import { createRouter, createWebHistory } from 'vue-router';
/ 全局前置守卫
router.beforeEach((to, from, next) => {
// 执行权限验证等操作
console.log('全局前置守卫');
next();
});
// 全局解析守卫
router.beforeResolve((to, from, next) => {
// 执行某些操作
console.log('全局解析守卫');
next();
});
// 全局后置守卫
router.afterEach((to, from) => {
// 执行某些操作
console.log('全局后置守卫');
});
- 全局前置守卫 (
beforeEach
): 在路由跳转之前执行,在导航开始时最早被调用,通常用于权限验证或登录判断。 - 全局解析守卫 (
beforeResolve
): 在导航被确认之前,所有组件内守卫和异步路由组件被解析之后调用。 - 全局后置守卫 (
afterEach
): 在路由跳转后执行,常用于页面加载完成后的操作,比如页面标题的更新。
其中函数的参数中
to 与 from : to指的是要导航到的组件,而from是从哪个组件来,to和from都是对象,可以从里面拿到路径,参数,等等一系列的数据
next : 一个函数,用于控制路由导航的流程
next()
:继续导航。next(false)
:取消导航。next({ path: '/new-path' })
:传入对象,与to中写法类似。next(new Error('Error message'))
:中断导航并传递错误。next(vm => { ... })
:在beforeRouteEnter
中使用,获取组件实例。
路由独享守卫
- 路由独享守卫 (
beforeEnter
): 在每次导航匹配到该路由时调用 ,只作用于某个具体的路由,可以在路由配置中定义,用于在特定路由进入前执行操作。
{
path: '/person',
name: 'person',
component: person,
beforeEnter: (to, from, next) => {
// 路由进入前的操作
console.log('路由独享守卫 person路由进入前的操作');
next();
}
},
独享守卫是在具体的某条路由规则里面配置的,因此需要写在规则中,且只有要路由到目标组件前时才触发 ,触发时机在beforeEach之后,beforeRouteEnter之前
组件内守卫
<script lang="ts" setup namespace="person">
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router';
// 离开前守卫
onBeforeRouteLeave((to, from) => {
console.log('组件路由离开前 beforeRouteLeave');
});
// 依然是当前组件,但是参数更新,如params,query参数
onBeforeRouteUpdate((to, from) => {
console.log('组件更新了Route updated');
});
</script>
<script lang="ts">
/*
这里请注意, vue3的setup,是组件创建时候的钩子
因此在setup里面是写不了beforeRouteEnter的
beforeRouteEnter是在导航进入该组件之前被调用的
*/
import { defineComponent } from 'vue';
export default defineComponent({
beforeRouteEnter(to, from, next) {
console.log('组件路由进入前 beforeRouteEnter');
next();
}})
</script>
路由进入有组件内路由守卫的组件
离开
在组件参数变化时候
- beforeRouteEnter: 在路由进入前执行的操作,但在组件实例被创建之前调用,因此不能访问组件实例 , 也不能写在vue3的 setup标签内。
- onBeforeRouteUpdate: 在路由更新时执行的操作,比如路由参数发生变化时。
- onBeforeRouteLeave: 在路由离开前执行的操作,可以访问组件实例。
总结
守卫执行顺序
导航到了不同的组件,执行顺序如下:
1. from 的组件内守卫 beforeRouteLeave (如果配置了)
2.全局前置守卫
3.to 的路由独享守卫 (如果配置了)
4.to 的组件内守卫beforeRouteEnter (如果配置了)
5. 全局解析守卫
6.全局后置守卫
导航到了相同的组件,但是参数发生了变化执行顺序如下:
1.全局前置守卫
2.组件内守卫onBeforeRouteUpdater (如果配置了)
3. 全局解析守卫
4.全局后置守卫
注意点
- 在使用路由守卫时,确保总是调用
next()
函数,除非你明确想要阻止导航。 - 如果守卫中包含异步操作,确保在异步操作完成后再调用
next()
,否则可能会导致路由被阻止。 - 多个守卫函数会按照注册的顺序依次执行,
afterEach
守卫会在所有守卫完成后执行。