10、Vue 3 - Vue Router 使用实录 : 路由守卫
Vue 3 中的 Vue Router 路由守卫是一种强大的功能,允许你在路由跳转过程中的不同阶段执行逻辑,比如权限检查、页面过渡控制等。
Vue Router 提供了全局前置拦截
、全局后置拦截
、单个路由拦截
的功能。
路由守卫机制
- 全局前置拦截:
beforeEach((to,from, next) => {})
,此时,路由未跳转 - 全局后置拦截:
afterEach((to,from,next) => {})
,此时,路由已跳转 - 单个路由拦截:
beforeEnter((to,from,next) => {})
,需要配置在路由中
参数说明:
-
to:要跳转的目标路由
-
from:从当前哪个路由进行跳转
-
next 函数
-
next()
表示放行,允许此次路由导航 -
next(false)
表示不放行,不允许此次路由导航 -
next({name:routerPath})
表示导航到该路由
-
单个路由拦截
本次将演示 单个路由拦截
和 全局前置路由拦截
。
1、添加组件
src/views/LoginView.vue
<template>
<h3>登录</h3>
</template>
<script setup lang="ts">
</script>
2、实现单个路由拦截
注意:单个路由的拦截,其使用位置是在路由中进行拦截。
src/router/index.ts
...
const router = createRouter({
history: createWebHistory(),
routes:[
...
{
path:'/login',
name:'login',
component: () => import('@/views/LoginView.vue'),
meta:{
'title':'登录',
},
// 拦截登录路由
beforeEnter: (to, from ,next) => {
console.log('单个拦截');
console.log(to);
// 放行路由,如果没有 next() 函数,路由将不会跳转
next()
}
},
]
})
...
3、测试
访问 http://localhost:5173/home
页面,打开 F12 ,然后点击 登录
按钮,并观察控制台中输出的信息。
全局前置路由拦截
演示全局前置路由时,我就不在添加新的路由及文件了。使用的是之前已经创建的路由及文件。
1、路由预览
注意:全局前置、后置拦截都需要在 router 对象上使用。
src/router/index.ts
import { createRouter, createWebHistory } from "vue-router"
const router = createRouter({
history: createWebHistory(),
routes:[
{
path:'/',
redirect:'/home'
},
{
path:'/home',
name:'home',
component: () => import('@/views/HomeView.vue'),
meta:{
'title':'首页',
},
children:[
{
path:'/home/contact',
name:'联系我',
components: {
contact:() => import('@/views/ContactView.vue')
}
},
{
path:'/home/category',
name:'分类',
components: {
category:() => import('@/views/CategoryView.vue')
}
}
]
},
{
path:'/about',
name:'about',
component: () => import('@/views/AboutView.vue'),
meta:{
'title':'关于'
},
children: [
{
path:'/about/post/:id',
name:"Post",
component: () => import('@/views/PostView.vue'),
props:true
}
]
},
{
path:'/:patchMatch(.*)',
name:'404',
component: () => import('@/views/404.vue')
},
{
path:'/login',
name:'login',
component: () => import('@/views/LoginView.vue'),
meta:{
'title':'登录',
},
// 拦截登录路由
beforeEnter: (to, from ,next) => {
console.log(to);
next()
}
},
]
})
export default router
2、使用全局前置路由
src/router/index.ts
...
// 全局前置拦截
router.beforeEach((to, from, next) => {
console.log('全局拦截');
console.log(to);
if (to?.meta?.title) {
document.title = '自如初-' + to.meta.title
}
next()
})
...
你应用要注意到,此时,存在两个拦截器。
3、测试
首先打开 F12,访问 http://localhost:5173/home/
并观察控制台的输出,此时,已经输出了相关信息。因为访问 home
,它自身就是一个路由,自然就要被拦截到咯。
点击关于我
按钮,再次看到相关信息的输出,此时,浏览器页面的 title
也发生了对应的变化。
4、前置和单个拦截,谁先生效?
上面提到有两个拦截器,前置拦截和单个拦截的问题,那么,当两个同时存在时,谁生效呢?不妨先猜测一下。
现在,我们回到首页 http://localhost:5173/home
,并清空控制台中的输出,然后点击登录
按钮,观察控制台中的输出,如下:
全局拦截
...
单个拦截
...
这个输出,如你所想吗?
关于后置拦截就不演示了,代码如下:
// src/router/index.ts
// 全局后置拦截
router.afterEach((to,from,next) => {
console.log('后置拦截');
console.log(to);
})
本系列到此结束,文档中没有记录到的,如有需要,后续补充。