export const Layout = () => import("@/layout/index.vue"); /** * 固定路由 */ const constRoutes = [ { path: "/login", component: () => import("@/views/login/index.vue"), meta: { hidden: true }, }, { path: "/404", component: () => import("@/views/error-page/404-permission.vue"), meta: { hidden: true }, }, // { // path: "/", // component: () => import("@/views/dashboard/Analysis/index1.vue"), // meta: { hidden: true }, // } ]; /** * home路由,需要修改redirect使用 */ const homeRoute = { path: '/', hidden: true, redirect: '' }; /** * 404兜底路由 */ const notFoundRoute = { path: '/:catchAll(.*)', redirect: '/404', hidden: true }; /** * 使用require加载组件,失败时弹出提示 * @param {string} path 组件路径 * @return {function} 加载组件的方法 */ async function getView(path: any) { const comps = import.meta.glob("../views/**/*.vue"); let match = comps[`../views${path}/index.vue`]; if (!match) { match = () => import("@/views/error-page/404.vue") } return (await match()).default; } /** * @typedef {Object} Menu * @property {number} parentId 父级菜单id * @property {boolean} leafFlag 是否是页面 * @property {boolean} hiddenFlag 是否是 * @property {string} routePath 路由路径 * @property {string} routeName 路由名称 * @property {string} componentPath 组件路径 * @property {string} menuName 菜单名称 * @property {string} icon 图标 * @property {string} title 标题 * @property {string} icon 图标 * @property {string} cacheFlag 是否缓存 * @property {string} affix 是否钉在 TAG 栏(暂未实现) */ /** * 后端menu转为路由 * @param {Menu} menu * @return {Object} {route, currRote} */ function generateParentRouter(menu: any) { // 顶级且是页面 if (menu.parentId === 'root' && menu.leafFlag) { const route = { path: menu.routePath, component: Layout, hidden: menu.hiddenFlag, icon: menu.icon, children: [ { path: '', name: menu.routeName || menu.id, // 取routeName作为每个页面的name,name必须对应才能有缓存 component: () => getView(menu.componentPath), meta: { title: menu.menuName, icon: menu.icon, cacheFlag: menu.cacheFlag, leafFlag: menu.leafFlag } } ], meta: {} }; return { route, currRoute: null }; } // 顶级且是菜单 if (menu.parentId === 'root' && !menu.leafFlag) { const route = { // alwaysShow 不管多少 children,都会展示展开箭头 alwaysShow: true, path: menu.routePath, name: menu.routeName || menu.id, component: Layout, hidden: menu.hiddenFlag, icon: menu.icon, // noRedirect 面包屑中是否可点击导航 meta: { title: menu.menuName, icon: menu.icon, noRedirect: true, cacheFlag: menu.cacheFlag, leafFlag: menu.leafFlag } }; return { route, currRoute: route }; } // 子级 if (menu.parentId !== 'root' && menu.leafFlag) { const route = { alwaysShow: !menu.leafFlag, path: menu.routePath, name: menu.routeName || menu.id, // 取routeName作为每个页面的name,name必须对应才能有缓存 component: () => getView(menu.componentPath), hidden: menu.hiddenFlag, icon: menu.icon, meta: { title: menu.menuName, icon: menu.icon, cacheFlag: menu.cacheFlag, leafFlag: menu.leafFlag } }; return { route, currRoute: route }; } if (menu.parentId !== null && !menu.leafFlag) { const route = { alwaysShow: !menu.leafFlag, path: menu.routePath, name: menu.routeName || menu.id, // hidden: menu.hiddenFlag, icon: menu.icon, meta: { title: menu.menuName, icon: menu.icon, cacheFlag: menu.cacheFlag, leafFlag: menu.leafFlag } }; return { route, currRoute: route }; } } /** * 转换后端menu列表为routes * 后端menu结构:{id,parentId,routeName,routePath,componentPath,menuName,leafFlag,icon} * @param {Menu[]} menuList * @return {Array} 路由数组 */ function convertAsyncRoutes(menuList: any) { if (!menuList || menuList.length <= 0) { return } const routes = []; for (let i = 0; i < menuList.length; i++) { const menu = menuList[i]; const menuRoute: any = generateParentRouter(menu); routes.push(menuRoute.route); if (menuRoute.currRoute && menu.children) { menuRoute.currRoute.children = convertAsyncRoutes(menu.children); } } return routes; } export { constRoutes, homeRoute, notFoundRoute, convertAsyncRoutes };