提交 dc42d434 编写于 作者: V vben

refactor: refactoring menu generation

上级 90b3fab2
......@@ -6,3 +6,7 @@ VITE_GLOB_APP_TITLE = Vben Admin
# spa shortname
VITE_GLOB_APP_SHORT_NAME = vue_vben_admin_2x
# Menu generation mode BACK|ROLE
# Need to delete LocalStorage after modification
VITE_GEN_MENU_MODE=ROLE
......@@ -8,6 +8,10 @@
- openModal 和 openDrawer 第二个参数可以代替`transferModalData`传参到内部
- 带参路由可以被缓存
### ✨ Refactor
- 重构由后台生成菜单的逻辑
### ⚡ Performance Improvements
- 菜单性能继续优化,更流畅
......
// Used to import all files under `src/views`
// The built-in dynamic import of vite cannot meet the needs of importing all files under views
import glob from 'glob';
import { Transform } from 'vite/dist/node/transform.js';
function getPath(path: string) {
const lastIndex = path.lastIndexOf('.');
if (lastIndex !== -1) {
path = path.substring(0, lastIndex);
}
return path.replace('src/views', '');
}
const dynamicImportTransform = function (env: any = {}): Transform {
return {
test({ path }) {
// Only convert the file
return path.includes('/src/utils/helper/dynamicImport.ts');
},
transform({ code }) {
const { VITE_GEN_MENU_MODE = '' } = env;
if (VITE_GEN_MENU_MODE !== 'BACK') {
return code;
}
// if (!isBuild) return code;
// Only convert the dir
try {
const files = glob.sync('src/views/**/**.{vue,tsx}', { cwd: process.cwd() });
const _code = `
export default function (id) {
switch (id) {
${files
.map((p) =>
` case '${getPath(p)}': return () => import('${p
.replace('src/views', '/@/views')
.replace(/\/\//g, '/')}');`.replace('.tsx', '')
)
.join('\n ')}
default: return Promise.reject(new Error("Unknown variable dynamic import: " + id));
}
}\n\n
`;
return _code;
} catch (error) {
console.error(error);
return code;
}
},
};
};
export default dynamicImportTransform;
......@@ -16,7 +16,7 @@ const dashboardRoute = {
{
path: '/welcome',
name: 'Welcome',
component: '/dashboard/welcome/index.vue',
component: '/dashboard/welcome/index',
meta: {
title: '欢迎页',
affix: true,
......@@ -34,28 +34,28 @@ const frontRoute = {
children: [
{
path: 'page',
component: '/demo/permission/front/index.vue',
component: '/demo/permission/front/index',
meta: {
title: '页面权限',
},
},
{
path: 'btn',
component: '/demo/permission/front/Btn.vue',
component: '/demo/permission/front/Btn',
meta: {
title: '按钮权限',
},
},
{
path: 'auth-pageA',
component: '/demo/permission/front/AuthPageA.vue',
component: '/demo/permission/front/AuthPageA',
meta: {
title: '权限测试页A',
},
},
{
path: 'auth-pageB',
component: '/demo/permission/front/AuthPageB.vue',
component: '/demo/permission/front/AuthPageB',
meta: {
title: '权限测试页B',
},
......@@ -71,14 +71,14 @@ const backRoute = {
children: [
{
path: 'page',
component: 'demo/permission/back/index.vue',
component: '/demo/permission/back/index',
meta: {
title: '页面权限',
},
},
{
path: 'btn',
component: '/demo/permission/back/Btn.vue',
component: '/demo/permission/back/Btn',
meta: {
title: '按钮权限',
},
......
......@@ -107,7 +107,9 @@ export default defineComponent({
unref(showHeaderRef) && <LayoutHeader />}
{showTabs && !unref(getFullContent) && (
<MultipleTabs class={`default-layout__tabs`} />
<Layout.Header class={`default-layout__tabs`}>
{() => <MultipleTabs />}
</Layout.Header>
)}
{useOpenBackTop && <BackTop target={getTarget} />}
......
import type { ProjectConfig } from '/@/types/config';
import { MenuTypeEnum, MenuThemeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum';
import { ContentEnum, PermissionModeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum';
import { primaryColor } from '../../build/config/lessModifyVars';
import { isProdMode } from '/@/utils/env';
import { isProdMode, getRoleMode } from '/@/utils/env';
// ! You need to clear the browser cache after the change
const setting: ProjectConfig = {
// Whether to show the configuration button
showSettingButton: true,
// 权限模式
permissionMode: PermissionModeEnum.ROLE,
permissionMode: getRoleMode(),
// 网站灰色模式,用于可能悼念的日期开启
grayMode: false,
// 色弱模式
......
......@@ -19,7 +19,7 @@ import { genRouteModule, transformObjToRoute } from '/@/utils/helper/routeHelper
import { transformRouteToMenu } from '/@/utils/helper/menuHelper';
import { useMessage } from '/@/hooks/web/useMessage';
import { warn } from '/@/utils/log';
// import { warn } from '/@/utils/log';
const { createMessage } = useMessage();
const NAME = 'permission';
......@@ -99,9 +99,9 @@ class Permission extends VuexModule {
});
// this.commitRoutesState(routes);
// Background permissions
warn(
`当前权限模式为:${PermissionModeEnum.ROLE},请将src/store/modules/permission.ts内的后台菜单获取函数注释,如果已注释可以忽略此信息!`
);
// warn(
// `当前权限模式为:${PermissionModeEnum.ROLE},请将src/store/modules/permission.ts内的后台菜单获取函数注释,如果已注释可以忽略此信息!`
// );
// 如果确定不需要做后台动态权限,请将下面整个判断注释
} else if (permissionMode === PermissionModeEnum.BACK) {
const messageKey = 'loadMenu';
......
import { PermissionModeEnum } from '../enums/appEnum';
import type { GlobEnvConfig } from '/@/types/config';
export const getGlobEnvConfig = (): GlobEnvConfig => {
......@@ -46,3 +47,14 @@ export const isProdMode = (): boolean => import.meta.env.PROD;
* @example:
*/
export const isUseMock = (): boolean => import.meta.env.VITE_USE_MOCK === 'true';
/**
* @description: 获取菜单生成方式
* @param {type}
* @returns:
* @example:
*/
export const getRoleMode = (): PermissionModeEnum =>
import.meta.env.VITE_GEN_MENU_MODE === PermissionModeEnum.ROLE
? PermissionModeEnum.ROLE
: PermissionModeEnum.BACK;
export default function (id: string) {
const dynamicImportModule: any = id;
return dynamicImportModule;
}
......@@ -6,6 +6,8 @@ import { tabStore } from '/@/store/modules/tab';
import { createRouter, createWebHashHistory } from 'vue-router';
import { toRaw } from 'vue';
import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant';
// import { isDevMode } from '/@/utils/env';
import dynamicImport from './dynamicImport';
let currentTo: RouteLocationNormalized | null = null;
......@@ -45,12 +47,12 @@ export function genRouteModule(moduleList: AppRouteModule[]) {
// TODO 错误写法
function asyncImportRoute(routes: AppRouteRecordRaw[]) {
routes.forEach((item) => {
let { component } = item;
const { component } = item;
const { children } = item;
if (component) {
component = component.replace(/^\//, '');
item.component = () => import(`/@/views/${component}`);
item.component = dynamicImport(component);
}
children && asyncImportRoute(children);
});
}
......
......@@ -5,6 +5,7 @@ import { resolve } from 'path';
import { modifyVars } from './build/config/lessModifyVars';
import { createProxy } from './build/vite/proxy';
import globbyTransform from './build/vite/plugin/context/transform';
import dynamicImportTransform from './build/vite/plugin/dynamicImport/index';
import { isDevFn, loadEnv } from './build/utils';
......@@ -134,5 +135,5 @@ const viteConfig: UserConfig = {
export default {
...viteConfig,
transforms: [globbyTransform(viteConfig)],
transforms: [globbyTransform(viteConfig), dynamicImportTransform(viteEnv)],
} as UserConfig;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册