赞
踩
示例前提:路由数组配置时,拆分成静态路由和动态路由,导出时配置的静态路由
import { defineStore } from "pinia"; const useUserStore = defineStore('userStore', () => { 这里是一些获取用户数据,储存数据的代码...省略... return { token, // 用户token role, // 用户角色 userInfo, // 用户信息 MyLogin, // 登陆方法 MyGetUserInfo, // 获取用户信息方法 ClearInfo // 清除信息数据 } }) export default useUserStore }
import { defineStore } from "pinia"; // 引入声明文件中自己定义的ts约束类型 import { MyRoutes, MyRoute } from "~/my-router"; // 引入静态路由和动态路由 import { constanceRoutes, asyncRoutes } from "@/router"; export const usePermissionStore = defineStore('permissionStore', () => { // 是否获取用户信息 const isGetUserInfo = ref(false) // 最终给导航栏使用的路由数组 const navRoutes = ref<MyRoutes>([]) // 修改用户信息状态 function setUserInfoState(flag: boolean) { isGetUserInfo.value = flag } // 判断单个路由权限,返回布尔值 function hasPermission(route: MyRoute, role: string) { // meta上有设置roles时则需要判断权限 if (route.meta?.roles) { return route.meta.roles.includes(role) } // 没有设置roles时则有权限 return true } // 判断多个路由权限,并筛选出有权限的路由数组 function filterAsyncRoutes(routes: MyRoutes, role: string) { // 创建临时路由数组 const tempArr: MyRoutes = [] // 遍历传入的多个路由数组 routes.forEach(route => { // 遍历出来的单个路由判断是否有权限(外层) if (hasPermission(route, role)) { // 如果有children,则递归遍历赋值(内层) if (route.children && route.children.length > 0) { route.children = filterAsyncRoutes(route.children, role) } // 有权限则添加该路由 tempArr.push(route) } }) // 返回筛选后的路由数组 return tempArr } // 生成动态路由 function generateRoute(role: string) { // 使用异步便于控制 return new Promise<MyRoutes>(resolve => { // 传入我们自己分组的动态路由,筛选出符合角色身份的路由数组 const accessRoutes = filterAsyncRoutes(asyncRoutes, role) // 将静态路由和新的动态路由拼接 navRoutes.value = [...constanceRoutes, ...accessRoutes] resolve(accessRoutes) }) } return { isGetUserInfo, navRoutes, setUserInfoState, generateRoute } }) export default usePermissionStore
yarn add nprogress
yarn add @types/nprogress
// 引入滚动条及样式 import NProgress from 'nprogress' import 'nprogress/nprogress.css' // 引入路由 import router from "./router"; // 引入权限仓库 import usePermissionStore from "./store/permissionStore"; // 引入用户信息仓库 import useUserStore from "./store/userStore"; // 滚动条配置 NProgress.configure({ showSpinner: false }) // 路由白名单 const whiteList = ['/login', '/404'] router.beforeEach(async (to, _from, next) => { // 开启滚动条 NProgress.start() // 实例仓库 const permissionStore = usePermissionStore() const userStore = useUserStore() // 1 判断是否有token const { token } = userStore if (token) { // 判断是否去login if (to.path === '/login') { // 不允许登陆状态切换用户,跳到首页 next('/') } else { // 判断是否获取到了用户信息 const { isGetUserInfo } = permissionStore // 如果有用户信息则放行 if (isGetUserInfo) { // 放行 next() } else { // 没有用户信息则尝试获取用户信息 try { await userStore.MyGetUserInfo() // 获取用户信息成功后: // 1 拿到角色 const { role } = userStore // 2 传入角色,获取动态路由 const accessRoutes = await permissionStore.generateRoute(role as string) // 3 遍历添加单个路由 accessRoutes.forEach(route => { router.addRoute(route) }) // 4 设置获取用户信息状态为true permissionStore.setUserInfoState(true) // hack方法,再跑一次 next({ ...to, replace: true }) } catch (error) { // 获取用户信息失败则重置信息且跳转到登陆页面 await userStore.ClearInfo() next('/login') } } } } else { // 判断是否去白名单 if (whiteList.includes(to.path)) { // 是则放行 next() } // 不是则去登陆 next(`/login?redirect=${to.fullPath}`) } }) // 后置守卫,结束滚动条 router.afterEach(() => { NProgress.done() })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。