import { RouteRecordRaw } from "vue-router"; import { constantRoutes } from "@/router"; import { store } from "@/store"; import MenuAPI, { RouteVO } from "@/api/menu"; const modules = import.meta.glob("../../views/**/**.vue"); const Layout = () => import("@/layout/index.vue"); export const usePermissionStore = defineStore("permission", () => { /** * 应用中所有的路由列表,包括静态路由和动态路由 */ const routes = ref([]); /** * 混合模式左侧菜单列表 */ const mixLeftMenus = ref([]); /** * 生成动态路由 */ function generateRoutes() { return new Promise((resolve, reject) => { MenuAPI.getRoutes() .then((data) => { const dynamicRoutes = transformRoutes(data); routes.value = constantRoutes.concat(dynamicRoutes); resolve(dynamicRoutes); }) .catch((error) => { reject(error); }); }); } /** * 混合模式菜单下根据顶部菜单路径设置左侧菜单 * * @param topMenuPath - 顶部菜单路径 */ const setMixLeftMenus = (topMenuPath: string) => { const matchedItem = routes.value.find((item) => item.path === topMenuPath); if (matchedItem && matchedItem.children) { mixLeftMenus.value = matchedItem.children; } }; return { routes, generateRoutes, mixLeftMenus, setMixLeftMenus, }; }); /** * 转换路由数据为组件 */ const transformRoutes = (routes: RouteVO[]) => { const asyncRoutes: RouteRecordRaw[] = []; routes.forEach((route) => { const tmpRoute = { ...route } as RouteRecordRaw; // 顶级目录,替换为 Layout 组件 if (tmpRoute.component?.toString() == "Layout") { tmpRoute.component = Layout; } else { // 其他菜单,根据组件路径动态加载组件 const component = modules[`../../views/${tmpRoute.component}.vue`]; if (component) { tmpRoute.component = component; } else { tmpRoute.component = modules[`../../views/error-page/404.vue`]; } } if (tmpRoute.children) { tmpRoute.children = transformRoutes(route.children); } asyncRoutes.push(tmpRoute); }); return asyncRoutes; }; /** * 用于在组件外部(如在Pinia Store 中)使用 Pinia 提供的 store 实例。 * 官方文档解释了如何在组件外部使用 Pinia Store: * https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component */ export function usePermissionStoreHook() { return usePermissionStore(store); }