在现代前端开发中,使用 Vue 3 和 TypeScript 的组合是一种流行且高效的开发方式。Vite 是一个极速的构建工具,可以显著提升开发体验。本文博主将指导你如何在 Vite + Vue 3 + TypeScript 项目中配置前置路由守卫(Navigation Guards)。
前置条件
在开始配置项目前置路由守卫前,博主希望你能够先达成以下前置条件:
1.完成Vue3前端项目搭建: Vite 创建 Vue3 + TS 项目
2.引入Vue-Router模块:Vue3项目配置Vue-Router
3.完成Pinia配置:Vue项目安装Pinia
1.创建前置守卫
在之前的章节中,我们已经完成了路由视图和路由重定向的配置,现在我们只需要为我们的路由器实例对象添加一个导航守卫就可以控制是否放行路由跳转啦。
我们可以通过
router.beforeEach
注册一个全局前置守卫,当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行的,导航在所有守卫 resolve 完之前一直处于等待中。
// 路由配置文件 index.ts
import { createWebHistory, createRouter } from 'vue-router'
// 定义路由配置
const routes: Array<any> = [
{
path: '/',
redirect: '/home'
},
{
path: '/login',
name: 'Login',
component: () => import('/@/views/login/index.vue')
},
{
path: '/home',
name: 'Home',
component: () => import('/@/views/home/index.vue'),
}
]
// 创建路由实例
const router = createRouter({
history: createWebHistory(), // 导航历史记录模式
routes
})
// 导航守卫
router.beforeEach((to, from) => {
// 返回 false 以取消导航
return false
})
// 导出实例
export default router
每个路由守卫都可以有以下三个参数:
- to:即将要进入的目标;
- from:当前导航正要离开的路由;
- next:当你在使用next时,确保
next
在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。
2.配置无token跳转登录页
既然知道了 Vue-Router 导航守卫的工作机制,那么我们现在可以尝试一下结合 Pinia 进行路由控制了:
2.1.配置User状态
在 src/store/ 目录下,新建 userInfo.ts 文件,用于存储 User/token 等状态:
// userInfo.ts
import { defineStore } from 'pinia'
import { reactive } from 'vue'
interface UserInfo {
token: string,
userId: string,
userName: string,
roles: Array<string>
}
export const useUserInfoStore = defineStore('userInfo', () => {
const state = reactive({
userInfo: {} as UserInfo
})
const setUserInfo = (userInfo: UserInfo) => {
state.userInfo = userInfo
}
const getUserInfo = () => {
return state.userInfo
}
return { state, setUserInfo, getUserInfo }
})
2.2.配置前置路由守卫
在 router.beforeEach
中根据token配置路由跳转:
// index.ts 路由配置文件
import { createWebHistory, createRouter } from 'vue-router'
// 引入我们刚才写好的 Pinia 状态
import { useUserInfoStore } from '/@/store/userInfo'
// 定义路由配置
const routes: Array<any> = [
{
path: '/',
redirect: '/home'
},
{
path: '/login',
name: 'Login',
component: () => import('/@/views/login/index.vue')
},
{
path: '/home',
name: 'Home',
component: () => import('/@/views/home/index.vue'),
}
]
// 创建路由实例
const router = createRouter({
history: createWebHistory(), // 导航历史记录模式
routes
})
// 导航守卫
router.beforeEach((to, from, next) => {
const userInfoStore = useUserInfoStore()
if ((to.path === '/login') && (!userInfoStore.state.userInfo.token)) {
next()
} else {
if (userInfoStore.state.userInfo.token) {
next()
} else {
next('/login')
}
}
})
// 导出实例
export default router
3.效果测试
项目根路径下(与src目录同级),运行命令行:
# 启动项目
$ npm run dev
可见,现在我们的pinia中没有存储的有token,所以在项目启动时,被全局前置守卫拦截下来,跳转到登录路由。