提交 dc42d434 编写于 作者: V vben

refactor: refactoring menu generation

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