import router from "./router"; import { useRouterStore } from "./pinia/router"; import { useMenuStore } from "./pinia/menu"; import { useUserStore } from "@/pinia/user"; import { useNavStore } from "@/pinia/nav"; import { cloneDeep } from "lodash-es"; import pinia from "./pinia"; import children from "@/components/children/index"; import { getAsyncRouter } from "@/request/api.js"; import conversionRouterMeta, { conversionNavMeta, } from "@/assets/js/conversion_router_meta.js"; import { resetQueryCriteria } from "@/hooks/useQueryCriteria.js"; const modules = import.meta.glob([ "./views/**/*.vue", "!./views/**/components/*.vue", ]); // 获取到views下所有的vue文件 let storageRouter = null; // 用来获取后台拿到的路由 let defaultModel = ""; router.beforeEach(async (to, from, next) => { const routerStore = useRouterStore(pinia); const menuStore = useMenuStore(pinia); const userStore = useUserStore(pinia); const navStore = useNavStore(pinia); // 需要登陆 if (to.meta.isLogin !== false) { if (!userStore.getUserInfo.userId) { next("/login"); return; } if (!storageRouter) { // 变量里没有储存路由 // pinia里没有储存路由,去后台获取路由 if (routerStore.getRouters.length === 0) { const { menuList, permissions, navList, defaultSelection } = await getAsyncRouter(); defaultModel = defaultSelection; userStore.setPermissions(permissions); storageRouter = conversionRouterMeta(menuList); // 后台请求得到的路由数据 navStore.setNavList(conversionNavMeta(navList)); routerStore.setRouters(storageRouter); // 存储路由 routerGo(to, next); // 执行路由跳转方法 } else { // pinia里储存了路由 storageRouter = routerStore.getRouters; // 拿到路由 routerGo(to, next); // 执行路由跳转方法 } } else { next(); } } else { // 不需要登陆,清空储存路由 storageRouter = null; routerStore.$reset(); menuStore.$reset(); navStore.$reset(); userStore.$reset(); resetQueryCriteria(); next(); } }); function routerGo(to, next) { const menuStore = useMenuStore(pinia); storageRouter = filterAsyncRouter(cloneDeep(storageRouter)); // 过滤路由 for (let i = 0; i < storageRouter.length; i++) { router.addRoute("app", storageRouter[i]); // 动态添加路由 } router.addRoute({ path: "/:pathMatch(.*)*", redirect: "/404" }); // 将404路由添加到最后 for (let i = 0; i < router.options.routes.length; i++) { if (router.options.routes[i].path === "/") { menuStore.setMenus( router.options.routes[i].children.concat(storageRouter) ); // 将路由数据存到一个新的pinia里,做菜单渲染 if (!menuStore.getModel) { menuStore.setModel(defaultModel); } break; } } next({ ...to, replace: true }); // 等待addRoute执行完毕跳转路由 } function filterAsyncRouter(asyncRouterMap) { // 遍历后台传来的路由字符串,转换为组件对象 return asyncRouterMap.filter((route) => { route.name = route.routeKey || ""; route.props = route.props === 1; if (route.component) { if (route.component === "children") { route.component = children; } else { if (route.component.charAt(0) === "/") { route.component = modules[`./views${route.component}.vue`]; } else { route.component = modules[`./views/${route.component}.vue`]; } } } // 如果存在children递归 if (route.list && route.list.length) { route.children = filterAsyncRouter(route.list); delete route.list; } return true; }); }