Files
vue3-element-admin/src/store/modules/permission.ts
2024-06-29 14:25:24 +08:00

94 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<RouteRecordRaw[]>([]);
/**
* 混合模式左侧菜单列表
*/
const mixLeftMenus = ref<RouteRecordRaw[]>([]);
/**
* 生成动态路由
*/
function generateRoutes(roles: string[]) {
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
MenuAPI.getRoutes(roles)
.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);
}