Commit 31e2715e674fc7d5144f39d8d5e595d904585af8

Authored by vben
1 parent 74378960

chore: detail optimization

build/script/updateHtml.ts
@@ -74,9 +74,7 @@ function injectCdnjs(html: string) { @@ -74,9 +74,7 @@ function injectCdnjs(html: string) {
74 export async function runUpdateHtml() { 74 export async function runUpdateHtml() {
75 const outDir = viteConfig.outDir || 'dist'; 75 const outDir = viteConfig.outDir || 'dist';
76 const indexPath = getCwdPath(outDir, 'index.html'); 76 const indexPath = getCwdPath(outDir, 'index.html');
77 - if (!existsSync(`${indexPath}`)) {  
78 - return;  
79 - } 77 + if (!existsSync(indexPath)) return;
80 try { 78 try {
81 let processedHtml = ''; 79 let processedHtml = '';
82 const rawHtml = readFileSync(indexPath, 'utf-8'); 80 const rawHtml = readFileSync(indexPath, 'utf-8');
@@ -92,7 +90,9 @@ export async function runUpdateHtml() { @@ -92,7 +90,9 @@ export async function runUpdateHtml() {
92 } 90 }
93 if (minify) { 91 if (minify) {
94 const { enable, ...miniOpt } = minify; 92 const { enable, ...miniOpt } = minify;
95 - processedHtml = HtmlMinifier.minify(processedHtml, miniOpt); 93 + if (enable) {
  94 + processedHtml = HtmlMinifier.minify(processedHtml, miniOpt);
  95 + }
96 } 96 }
97 97
98 writeFileSync(indexPath, processedHtml); 98 writeFileSync(indexPath, processedHtml);
build/transform/require-context/index.ts 0 → 100644
  1 +// https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts
  2 +
  3 +// TODO 目前还不能监听文件新增及删除 内容已经改变,缓存问题?
  4 +// 可以使用,先不打算集成
  5 +import { join } from 'path';
  6 +import { lstatSync } from 'fs';
  7 +import glob from 'glob';
  8 +import { createResolver, Resolver } from 'vite/dist/node/resolver.js';
  9 +import { Transform } from 'vite/dist/node/transform.js';
  10 +
  11 +const modulesDir: string = join(process.cwd(), '/node_modules/');
  12 +
  13 +interface SharedConfig {
  14 + root?: string;
  15 + alias?: Record<string, string>;
  16 + resolvers?: Resolver[];
  17 +}
  18 +
  19 +function template(template: string) {
  20 + return (data: { [x: string]: any }) => {
  21 + return template.replace(/#([^#]+)#/g, (_, g1) => data[g1] || g1);
  22 + };
  23 +}
  24 +
  25 +const globbyTransform = function (config: SharedConfig): Transform {
  26 + const resolver = createResolver(
  27 + config.root || process.cwd(),
  28 + config.resolvers || [],
  29 + config.alias || {}
  30 + );
  31 + const cache = new Map();
  32 +
  33 + const urlMap = new Map();
  34 + return {
  35 + test({ path }) {
  36 + const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
  37 + try {
  38 + return (
  39 + !filePath.startsWith(modulesDir) &&
  40 + /\.(vue|js|jsx|ts|tsx)$/.test(filePath) &&
  41 + lstatSync(filePath).isFile()
  42 + );
  43 + } catch {
  44 + return false;
  45 + }
  46 + },
  47 + transform({ code, path, isBuild }) {
  48 + let result = cache.get(path);
  49 + if (!result) {
  50 + const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?path)?!([^'"]+)\2/g;
  51 + const lastImport = urlMap.get(path);
  52 + const match = code.match(reg);
  53 + if (lastImport && match) {
  54 + code = code.replace(lastImport, match[0]);
  55 + }
  56 + result = code.replace(reg, (_, g1, g2, g3, g4) => {
  57 + const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
  58 + // resolve path
  59 + const resolvedFilePath = g4.startsWith('.')
  60 + ? resolver.resolveRelativeRequest(filePath, g4)
  61 + : { pathname: resolver.requestToFile(g4) };
  62 + const files = glob.sync(resolvedFilePath.pathname, { dot: true });
  63 + let templateStr = 'import #name# from #file#'; // import default
  64 + let name = g1;
  65 + const m = g1.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module
  66 + const m2 = g1.match(/\*\s+as\s+(\w+)/); // import * as all module
  67 + if (m) {
  68 + templateStr = `import { ${m[1]} as #name# } from #file#`;
  69 + name = m[3] || m[1];
  70 + } else if (m2) {
  71 + templateStr = 'import * as #name# from #file#';
  72 + name = m2[1];
  73 + }
  74 + const temRender = template(templateStr);
  75 +
  76 + const groups: Array<string>[] = [];
  77 + const replaceFiles = files.map((f, i) => {
  78 + const file = g2 + resolver.fileToRequest(f) + g2;
  79 + groups.push([name + i, file]);
  80 + return temRender({ name: name + i, file });
  81 + });
  82 + urlMap.set(path, replaceFiles.join('\n'));
  83 + return (
  84 + replaceFiles.join('\n') +
  85 + (g3 ? '\n' + groups.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : '') +
  86 + `\nconst ${name} = { ${groups.map((v) => v[0]).join(',')} }\n`
  87 + );
  88 + });
  89 + if (isBuild) cache.set(path, result);
  90 + }
  91 + return result;
  92 + },
  93 + };
  94 +};
  95 +export default globbyTransform;
build/utils.ts
@@ -124,28 +124,24 @@ export function getEnvConfig(match = &#39;VITE_GLOB_&#39;, confFiles = [&#39;.env&#39;, &#39;.env.pr @@ -124,28 +124,24 @@ export function getEnvConfig(match = &#39;VITE_GLOB_&#39;, confFiles = [&#39;.env&#39;, &#39;.env.pr
124 return envConfig; 124 return envConfig;
125 } 125 }
126 126
127 -export function successConsole(message: any) { 127 +function consoleFn(color: string, message: any) {
128 console.log( 128 console.log(
129 chalk.blue.bold('**************** ') + 129 chalk.blue.bold('**************** ') +
130 - chalk.green.bold('✨ ' + message) + 130 + (chalk as any)[color].bold(message) +
131 chalk.blue.bold(' ****************') 131 chalk.blue.bold(' ****************')
132 ); 132 );
133 } 133 }
134 134
  135 +export function successConsole(message: any) {
  136 + consoleFn('green', '✨ ' + message);
  137 +}
  138 +
135 export function errorConsole(message: any) { 139 export function errorConsole(message: any) {
136 - console.log(  
137 - chalk.blue.bold('**************** ') +  
138 - chalk.red.bold('✨ ' + message) +  
139 - chalk.blue.bold(' ****************')  
140 - ); 140 + consoleFn('red', '✨ ' + message);
141 } 141 }
142 142
143 export function warnConsole(message: any) { 143 export function warnConsole(message: any) {
144 - console.log(  
145 - chalk.blue.bold('**************** ') +  
146 - chalk.yellow.bold('✨ ' + message) +  
147 - chalk.blue.bold(' ****************')  
148 - ); 144 + consoleFn('yellow', '✨ ' + message);
149 } 145 }
150 146
151 export function getCwdPath(...dir: string[]) { 147 export function getCwdPath(...dir: string[]) {
src/components/CountTo/src/index.vue
@@ -5,7 +5,6 @@ @@ -5,7 +5,6 @@
5 </template> 5 </template>
6 <script lang="ts"> 6 <script lang="ts">
7 import { defineComponent, reactive, computed, watch, onMounted, unref, toRef } from 'vue'; 7 import { defineComponent, reactive, computed, watch, onMounted, unref, toRef } from 'vue';
8 -  
9 import { countToProps } from './props'; 8 import { countToProps } from './props';
10 import { useRaf } from '/@/hooks/event/useRaf'; 9 import { useRaf } from '/@/hooks/event/useRaf';
11 import { isNumber } from '/@/utils/is'; 10 import { isNumber } from '/@/utils/is';
@@ -37,12 +36,14 @@ @@ -37,12 +36,14 @@
37 remaining: null, 36 remaining: null,
38 rAF: null, 37 rAF: null,
39 }); 38 });
  39 +
40 onMounted(() => { 40 onMounted(() => {
41 if (props.autoplay) { 41 if (props.autoplay) {
42 start(); 42 start();
43 } 43 }
44 emit('mounted'); 44 emit('mounted');
45 }); 45 });
  46 +
46 const getCountDown = computed(() => { 47 const getCountDown = computed(() => {
47 return props.startVal > props.endVal; 48 return props.startVal > props.endVal;
48 }); 49 });
@@ -61,6 +62,7 @@ @@ -61,6 +62,7 @@
61 state.paused = false; 62 state.paused = false;
62 state.rAF = requestAnimationFrame(count); 63 state.rAF = requestAnimationFrame(count);
63 } 64 }
  65 +
64 function pauseResume() { 66 function pauseResume() {
65 if (state.paused) { 67 if (state.paused) {
66 resume(); 68 resume();
@@ -70,6 +72,7 @@ @@ -70,6 +72,7 @@
70 state.paused = true; 72 state.paused = true;
71 } 73 }
72 } 74 }
  75 +
73 function pause() { 76 function pause() {
74 cancelAnimationFrame(state.rAF); 77 cancelAnimationFrame(state.rAF);
75 } 78 }
src/components/Menu/src/BasicMenu.tsx
@@ -7,7 +7,7 @@ import { Menu } from &#39;ant-design-vue&#39;; @@ -7,7 +7,7 @@ import { Menu } from &#39;ant-design-vue&#39;;
7 import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; 7 import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
8 import { menuStore } from '/@/store/modules/menu'; 8 import { menuStore } from '/@/store/modules/menu';
9 import { getSlot } from '/@/utils/helper/tsxHelper'; 9 import { getSlot } from '/@/utils/helper/tsxHelper';
10 -import { ScrollContainer } from '/@/components/Container/index'; 10 +// import { ScrollContainer } from '/@/components/Container/index';
11 import SearchInput from './SearchInput.vue'; 11 import SearchInput from './SearchInput.vue';
12 import './index.less'; 12 import './index.less';
13 import { menuHasChildren } from './helper'; 13 import { menuHasChildren } from './helper';
@@ -67,6 +67,7 @@ export default defineComponent({ @@ -67,6 +67,7 @@ export default defineComponent({
67 return { 67 return {
68 height: `calc(100% - ${offset}px)`, 68 height: `calc(100% - ${offset}px)`,
69 position: 'relative', 69 position: 'relative',
  70 + overflow: 'auto',
70 }; 71 };
71 }); 72 });
72 73
@@ -246,8 +247,9 @@ export default defineComponent({ @@ -246,8 +247,9 @@ export default defineComponent({
246 onClick={handleInputClick} 247 onClick={handleInputClick}
247 collapsed={getCollapsedState} 248 collapsed={getCollapsedState}
248 /> 249 />
249 - <section style={unref(getMenuWrapStyle)}>  
250 - <ScrollContainer>{() => renderMenu()}</ScrollContainer> 250 + <section style={unref(getMenuWrapStyle)} class="basic-menu__wrap">
  251 + {renderMenu()}
  252 + {/* <ScrollContainer>{() => renderMenu()}</ScrollContainer> */}
251 </section> 253 </section>
252 </section> 254 </section>
253 ); 255 );
src/components/Menu/src/index.less
@@ -14,6 +14,30 @@ @@ -14,6 +14,30 @@
14 } 14 }
15 15
16 .basic-menu { 16 .basic-menu {
  17 + &__wrap {
  18 + /* 滚动槽 */
  19 + &::-webkit-scrollbar {
  20 + width: 6px;
  21 + height: 6px;
  22 + }
  23 +
  24 + // TODO 滚动条样式-待修改
  25 + &::-webkit-scrollbar-track {
  26 + background: rgba(0, 0, 0, 0);
  27 + }
  28 +
  29 + /* 滚动条滑块 */
  30 + &::-webkit-scrollbar-thumb {
  31 + background: rgba(255, 255, 255, 0.3);
  32 + border-radius: 4px;
  33 + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
  34 + }
  35 +
  36 + ::-webkit-scrollbar-thumb:hover {
  37 + background: @border-color-dark;
  38 + }
  39 + }
  40 +
17 .ant-menu-submenu:first-of-type { 41 .ant-menu-submenu:first-of-type {
18 margin-top: 4px; 42 margin-top: 4px;
19 } 43 }
@@ -95,14 +119,14 @@ @@ -95,14 +119,14 @@
95 .ant-menu-submenu-active, 119 .ant-menu-submenu-active,
96 .ant-menu-submenu-title:hover { 120 .ant-menu-submenu-title:hover {
97 background: @top-menu-active-bg-color; 121 background: @top-menu-active-bg-color;
98 - border-radius: 6px 6px 0 0; 122 + // border-radius: 6px 6px 0 0;
99 } 123 }
100 124
101 .basic-menu-item__level1 { 125 .basic-menu-item__level1 {
102 &.ant-menu-item-selected, 126 &.ant-menu-item-selected,
103 &.ant-menu-submenu-selected { 127 &.ant-menu-submenu-selected {
104 background: @top-menu-active-bg-color; 128 background: @top-menu-active-bg-color;
105 - border-radius: 6px 6px 0 0; 129 + // border-radius: 6px 6px 0 0;
106 } 130 }
107 } 131 }
108 132
@@ -148,6 +172,10 @@ @@ -148,6 +172,10 @@
148 } 172 }
149 173
150 .basic-menu-item__level1 { 174 .basic-menu-item__level1 {
  175 + > .ant-menu-sub > li {
  176 + background-color: @sub-menu-item-dark-bg-color;
  177 + }
  178 +
151 margin-bottom: 0; 179 margin-bottom: 0;
152 180
153 &.top-active-menu { 181 &.top-active-menu {
@@ -179,7 +207,7 @@ @@ -179,7 +207,7 @@
179 207
180 .ant-menu-submenu-title { 208 .ant-menu-submenu-title {
181 height: @app-menu-item-height; 209 height: @app-menu-item-height;
182 - margin: 0; 210 + // margin: 0;
183 line-height: @app-menu-item-height; 211 line-height: @app-menu-item-height;
184 } 212 }
185 } 213 }
src/design/var/index.less
@@ -18,4 +18,4 @@ @@ -18,4 +18,4 @@
18 // app menu 18 // app menu
19 19
20 // left-menu 20 // left-menu
21 -@app-menu-item-height: 44px; 21 +@app-menu-item-height: 48px;
src/hooks/web/useTabs.ts
1 -import type { AppRouteRecordRaw } from '/@/router/types.d';  
2 import { useTimeout } from '/@/hooks/core/useTimeout'; 1 import { useTimeout } from '/@/hooks/core/useTimeout';
3 import { PageEnum } from '/@/enums/pageEnum'; 2 import { PageEnum } from '/@/enums/pageEnum';
4 import { TabItem, tabStore } from '/@/store/modules/tab'; 3 import { TabItem, tabStore } from '/@/store/modules/tab';
5 import { appStore } from '/@/store/modules/app'; 4 import { appStore } from '/@/store/modules/app';
6 import router from '/@/router'; 5 import router from '/@/router';
7 import { ref } from 'vue'; 6 import { ref } from 'vue';
  7 +import { pathToRegexp } from 'path-to-regexp';
8 8
9 const activeKeyRef = ref<string>(''); 9 const activeKeyRef = ref<string>('');
10 10
@@ -68,7 +68,11 @@ export function useTabs() { @@ -68,7 +68,11 @@ export function useTabs() {
68 function getTo(path: string): any { 68 function getTo(path: string): any {
69 const routes = router.getRoutes(); 69 const routes = router.getRoutes();
70 const fn = (p: string): any => { 70 const fn = (p: string): any => {
71 - const to = routes.find((item) => item.path === p); 71 + const to = routes.find((item) => {
  72 + if (item.path === '/:path(.*)*') return;
  73 + const regexp = pathToRegexp(item.path);
  74 + return regexp.test(p);
  75 + });
72 if (!to) return ''; 76 if (!to) return '';
73 if (!to.redirect) return to; 77 if (!to.redirect) return to;
74 if (to.redirect) { 78 if (to.redirect) {
@@ -88,12 +92,13 @@ export function useTabs() { @@ -88,12 +92,13 @@ export function useTabs() {
88 resetCache: () => canIUseFn() && resetCache(), 92 resetCache: () => canIUseFn() && resetCache(),
89 addTab: (path: PageEnum, goTo = false, replace = false) => { 93 addTab: (path: PageEnum, goTo = false, replace = false) => {
90 const to = getTo(path); 94 const to = getTo(path);
  95 +
91 if (!to) return; 96 if (!to) return;
92 useTimeout(() => { 97 useTimeout(() => {
93 - tabStore.addTabByPathAction((to as unknown) as AppRouteRecordRaw); 98 + tabStore.addTabByPathAction();
94 }, 0); 99 }, 0);
95 - activeKeyRef.value = to.path;  
96 - goTo && replace ? router.replace : router.push(to.path); 100 + activeKeyRef.value = path;
  101 + goTo && replace ? router.replace : router.push(path);
97 }, 102 },
98 activeKeyRef, 103 activeKeyRef,
99 }; 104 };
src/layouts/default/index.tsx
@@ -82,10 +82,13 @@ export default defineComponent({ @@ -82,10 +82,13 @@ export default defineComponent({
82 {() => ( 82 {() => (
83 <> 83 <>
84 {isLock && <LockPage />} 84 {isLock && <LockPage />}
  85 +
85 {!unref(getFullContent) && unref(isShowMixHeaderRef) && unref(showHeaderRef) && ( 86 {!unref(getFullContent) && unref(isShowMixHeaderRef) && unref(showHeaderRef) && (
86 <LayoutHeader /> 87 <LayoutHeader />
87 )} 88 )}
  89 +
88 {showSettingButton && <SettingBtn />} 90 {showSettingButton && <SettingBtn />}
  91 +
89 <Layout> 92 <Layout>
90 {() => ( 93 {() => (
91 <> 94 <>
@@ -102,7 +105,9 @@ export default defineComponent({ @@ -102,7 +105,9 @@ export default defineComponent({
102 {() => <MultipleTabs />} 105 {() => <MultipleTabs />}
103 </Layout.Header> 106 </Layout.Header>
104 )} 107 )}
  108 +
105 {useOpenBackTop && <BackTop target={getTarget} />} 109 {useOpenBackTop && <BackTop target={getTarget} />}
  110 +
106 <div class={[`default-layout__main`, fixedHeaderCls]}> 111 <div class={[`default-layout__main`, fixedHeaderCls]}>
107 {openPageLoading && ( 112 {openPageLoading && (
108 <FullLoading 113 <FullLoading
src/layouts/default/multitabs/index.tsx
@@ -9,6 +9,7 @@ import { @@ -9,6 +9,7 @@ import {
9 // ref, 9 // ref,
10 unref, 10 unref,
11 onMounted, 11 onMounted,
  12 + toRaw,
12 } from 'vue'; 13 } from 'vue';
13 import { Tabs } from 'ant-design-vue'; 14 import { Tabs } from 'ant-design-vue';
14 import TabContent from './TabContent'; 15 import TabContent from './TabContent';
@@ -73,11 +74,7 @@ export default defineComponent({ @@ -73,11 +74,7 @@ export default defineComponent({
73 routes && 74 routes &&
74 routes.forEach((route) => { 75 routes.forEach((route) => {
75 if (route.meta && route.meta.affix) { 76 if (route.meta && route.meta.affix) {
76 - tabs.push({  
77 - path: route.path,  
78 - name: route.name,  
79 - meta: { ...route.meta },  
80 - }); 77 + tabs.push(toRaw(route) as TabItem);
81 } 78 }
82 }); 79 });
83 return tabs; 80 return tabs;
@@ -114,7 +111,7 @@ export default defineComponent({ @@ -114,7 +111,7 @@ export default defineComponent({
114 }; 111 };
115 return ( 112 return (
116 <span> 113 <span>
117 - <TabContent {...tabContentProps} /> 114 + <TabContent {...(tabContentProps as any)} />
118 </span> 115 </span>
119 ); 116 );
120 } 117 }
src/layouts/page/index.tsx
@@ -40,7 +40,8 @@ export default defineComponent({ @@ -40,7 +40,8 @@ export default defineComponent({
40 <RouterView> 40 <RouterView>
41 {{ 41 {{
42 default: ({ Component, route }: { Component: any; route: RouteLocation }) => { 42 default: ({ Component, route }: { Component: any; route: RouteLocation }) => {
43 - const name = route.meta.inTab ? ' ' : null; 43 + // 已经位于tab内的不再显示动画
  44 + const name = route.meta.inTab ? 'fade' : null;
44 const Content = openCache ? ( 45 const Content = openCache ? (
45 <KeepAlive max={max} include={cacheTabs}> 46 <KeepAlive max={max} include={cacheTabs}>
46 <Component {...route.params} /> 47 <Component {...route.params} />
src/router/guard/index.ts
@@ -7,7 +7,7 @@ import { createProgressGuard } from &#39;./progressGuard&#39;; @@ -7,7 +7,7 @@ import { createProgressGuard } from &#39;./progressGuard&#39;;
7 import { createPermissionGuard } from './permissionGuard'; 7 import { createPermissionGuard } from './permissionGuard';
8 import { createPageLoadingGuard } from './pageLoadingGuard'; 8 import { createPageLoadingGuard } from './pageLoadingGuard';
9 import { useSetting } from '/@/hooks/core/useSetting'; 9 import { useSetting } from '/@/hooks/core/useSetting';
10 -import { getIsOpenTab } from '/@/utils/helper/routeHelper'; 10 +import { getIsOpenTab, setCurrentTo } from '/@/utils/helper/routeHelper';
11 11
12 const { projectSetting } = useSetting(); 12 const { projectSetting } = useSetting();
13 export function createGuard(router: Router) { 13 export function createGuard(router: Router) {
@@ -17,7 +17,7 @@ export function createGuard(router: Router) { @@ -17,7 +17,7 @@ export function createGuard(router: Router) {
17 axiosCanceler = new AxiosCanceler(); 17 axiosCanceler = new AxiosCanceler();
18 } 18 }
19 router.beforeEach(async (to) => { 19 router.beforeEach(async (to) => {
20 - const isOpen = getIsOpenTab(to.path); 20 + const isOpen = getIsOpenTab(to.fullPath);
21 to.meta.inTab = isOpen; 21 to.meta.inTab = isOpen;
22 try { 22 try {
23 if (closeMessageOnSwitch) { 23 if (closeMessageOnSwitch) {
@@ -30,6 +30,8 @@ export function createGuard(router: Router) { @@ -30,6 +30,8 @@ export function createGuard(router: Router) {
30 } catch (error) { 30 } catch (error) {
31 console.warn('basic guard error:' + error); 31 console.warn('basic guard error:' + error);
32 } 32 }
  33 + setCurrentTo(to);
  34 + return true;
33 }); 35 });
34 openNProgress && createProgressGuard(router); 36 openNProgress && createProgressGuard(router);
35 createPermissionGuard(router); 37 createPermissionGuard(router);
src/router/guard/pageLoadingGuard.ts
@@ -2,6 +2,7 @@ import type { Router } from &#39;vue-router&#39;; @@ -2,6 +2,7 @@ import type { Router } from &#39;vue-router&#39;;
2 import { tabStore } from '/@/store/modules/tab'; 2 import { tabStore } from '/@/store/modules/tab';
3 import { appStore } from '/@/store/modules/app'; 3 import { appStore } from '/@/store/modules/app';
4 import { userStore } from '/@/store/modules/user'; 4 import { userStore } from '/@/store/modules/user';
  5 +import { getParams } from '/@/utils/helper/routeHelper';
5 6
6 export function createPageLoadingGuard(router: Router) { 7 export function createPageLoadingGuard(router: Router) {
7 let isFirstLoad = true; 8 let isFirstLoad = true;
@@ -29,9 +30,16 @@ export function createPageLoadingGuard(router: Router) { @@ -29,9 +30,16 @@ export function createPageLoadingGuard(router: Router) {
29 } 30 }
30 return true; 31 return true;
31 }); 32 });
32 - router.afterEach(async (to) => { 33 + router.afterEach(async (to, from) => {
33 const { openRouterTransition, openPageLoading } = appStore.getProjectConfig; 34 const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
34 - if ((!openRouterTransition && openPageLoading) || isFirstLoad || to.meta.afterCloseLoading) { 35 + const realToPath = to.path.replace(getParams(to), '');
  36 + const realFormPath = from.path.replace(getParams(from), '');
  37 + if (
  38 + (!openRouterTransition && openPageLoading) ||
  39 + isFirstLoad ||
  40 + to.meta.afterCloseLoading ||
  41 + realToPath === realFormPath
  42 + ) {
35 setTimeout(() => { 43 setTimeout(() => {
36 appStore.commitPageLoadingState(false); 44 appStore.commitPageLoadingState(false);
37 }, 110); 45 }, 110);
src/router/menus/index.ts
@@ -107,7 +107,8 @@ export async function getFlatChildrenMenus(children: Menu[]) { @@ -107,7 +107,8 @@ export async function getFlatChildrenMenus(children: Menu[]) {
107 function basicFilter(routes: RouteRecordNormalized[]) { 107 function basicFilter(routes: RouteRecordNormalized[]) {
108 return (menu: Menu) => { 108 return (menu: Menu) => {
109 const matchRoute = routes.find((route) => route.path === menu.path); 109 const matchRoute = routes.find((route) => route.path === menu.path);
110 - if (!matchRoute) return false; 110 +
  111 + if (!matchRoute) return true;
111 menu.icon = menu.icon || matchRoute.meta.icon; 112 menu.icon = menu.icon || matchRoute.meta.icon;
112 menu.meta = matchRoute.meta; 113 menu.meta = matchRoute.meta;
113 return true; 114 return true;
src/router/menus/modules/demo/feat.ts
@@ -45,6 +45,20 @@ const menu: MenuModule = { @@ -45,6 +45,20 @@ const menu: MenuModule = {
45 path: '/full-screen', 45 path: '/full-screen',
46 name: '全屏', 46 name: '全屏',
47 }, 47 },
  48 + {
  49 + path: '/testTab',
  50 + name: '带参Tab',
  51 + children: [
  52 + {
  53 + path: '/id1',
  54 + name: '带参tab1',
  55 + },
  56 + {
  57 + path: '/id2',
  58 + name: '带参tab2',
  59 + },
  60 + ],
  61 + },
48 ], 62 ],
49 }, 63 },
50 }; 64 };
src/router/routes/index.ts
@@ -3,8 +3,6 @@ import type { AppRouteRecordRaw, AppRouteModule } from &#39;/@/router/types&#39;; @@ -3,8 +3,6 @@ import type { AppRouteRecordRaw, AppRouteModule } from &#39;/@/router/types&#39;;
3 import { DEFAULT_LAYOUT_COMPONENT, PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '../constant'; 3 import { DEFAULT_LAYOUT_COMPONENT, PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '../constant';
4 import { genRouteModule } from '/@/utils/helper/routeHelper'; 4 import { genRouteModule } from '/@/utils/helper/routeHelper';
5 5
6 -import LoginRoute from './modules/sys';  
7 -  
8 import dashboard from './modules/dashboard'; 6 import dashboard from './modules/dashboard';
9 7
10 // demo 8 // demo
@@ -48,5 +46,14 @@ export const RootRoute: AppRouteRecordRaw = { @@ -48,5 +46,14 @@ export const RootRoute: AppRouteRecordRaw = {
48 children: [], 46 children: [],
49 }; 47 };
50 48
  49 +export const LoginRoute: AppRouteRecordRaw = {
  50 + path: '/login',
  51 + name: 'Login',
  52 + component: () => import('/@/views/sys/login/Login.vue'),
  53 + meta: {
  54 + title: '登录',
  55 + },
  56 +};
  57 +
51 // 基础路由 不用权限 58 // 基础路由 不用权限
52 export const basicRoutes = [LoginRoute, RootRoute]; 59 export const basicRoutes = [LoginRoute, RootRoute];
src/router/routes/modules/demo/feat.ts
@@ -96,5 +96,13 @@ export default { @@ -96,5 +96,13 @@ export default {
96 title: '全屏', 96 title: '全屏',
97 }, 97 },
98 }, 98 },
  99 + {
  100 + path: '/testTab/:id',
  101 + name: 'TestTab',
  102 + component: () => import('/@/views/demo/feat/tab-params/index.vue'),
  103 + meta: {
  104 + title: 'Tab带参',
  105 + },
  106 + },
99 ], 107 ],
100 } as AppRouteModule; 108 } as AppRouteModule;
src/router/routes/modules/sys.ts deleted 100644 → 0
1 -import type { AppRouteRecordRaw } from '/@/router/types';  
2 -  
3 -const routes: AppRouteRecordRaw = {  
4 - path: '/login',  
5 - name: 'Login',  
6 - component: () => import('/@/views/sys/login/Login.vue'),  
7 - meta: {  
8 - title: '登录',  
9 - },  
10 -};  
11 -  
12 -export default routes;  
src/router/types.d.ts
@@ -39,6 +39,7 @@ export interface AppRouteRecordRaw extends Omit&lt;RouteRecordRaw, &#39;meta&#39;&gt; { @@ -39,6 +39,7 @@ export interface AppRouteRecordRaw extends Omit&lt;RouteRecordRaw, &#39;meta&#39;&gt; {
39 components?: any; 39 components?: any;
40 children?: AppRouteRecordRaw[]; 40 children?: AppRouteRecordRaw[];
41 props?: any; 41 props?: any;
  42 + fullPath?: string;
42 } 43 }
43 44
44 export interface Menu { 45 export interface Menu {
src/store/modules/tab.ts
@@ -11,6 +11,7 @@ import { appStore } from &#39;/@/store/modules/app&#39;; @@ -11,6 +11,7 @@ import { appStore } from &#39;/@/store/modules/app&#39;;
11 import store from '/@/store'; 11 import store from '/@/store';
12 import router from '/@/router'; 12 import router from '/@/router';
13 import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant'; 13 import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant';
  14 +import { getCurrentTo } from '/@/utils/helper/routeHelper';
14 15
15 type CacheName = string | symbol | null | undefined; 16 type CacheName = string | symbol | null | undefined;
16 /** 17 /**
@@ -18,7 +19,10 @@ type CacheName = string | symbol | null | undefined; @@ -18,7 +19,10 @@ type CacheName = string | symbol | null | undefined;
18 */ 19 */
19 // declare namespace TabsStore { 20 // declare namespace TabsStore {
20 export interface TabItem { 21 export interface TabItem {
21 - path: string; 22 + fullPath: string;
  23 + path?: string;
  24 + params?: any;
  25 + query?: any;
22 name?: CacheName; 26 name?: CacheName;
23 meta?: RouteMeta; 27 meta?: RouteMeta;
24 } 28 }
@@ -86,20 +90,21 @@ class Tab extends VuexModule { @@ -86,20 +90,21 @@ class Tab extends VuexModule {
86 */ 90 */
87 @Mutation 91 @Mutation
88 commitAddTab(route: AppRouteRecordRaw | TabItem): void { 92 commitAddTab(route: AppRouteRecordRaw | TabItem): void {
89 - const { path, name, meta } = route; 93 + const { path, name, meta, fullPath, params, query } = route as TabItem;
90 // 404 页面不需要添加tab 94 // 404 页面不需要添加tab
91 if (path === PageEnum.ERROR_PAGE) { 95 if (path === PageEnum.ERROR_PAGE) {
92 return; 96 return;
93 } else if ([REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)) { 97 } else if ([REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)) {
94 return; 98 return;
95 } 99 }
  100 +
96 // 已经存在的页面,不重复添加tab 101 // 已经存在的页面,不重复添加tab
97 const hasTab = this.tabsState.some((tab) => { 102 const hasTab = this.tabsState.some((tab) => {
98 - return tab.path === path; 103 + return tab.fullPath === fullPath;
99 }); 104 });
100 if (hasTab) return; 105 if (hasTab) return;
101 106
102 - this.tabsState.push({ path, name, meta }); 107 + this.tabsState.push({ path, fullPath, name, meta, params, query });
103 if (unref(getOpenKeepAliveRef) && name) { 108 if (unref(getOpenKeepAliveRef) && name) {
104 const noKeepAlive = meta && meta.ignoreKeepAlive; 109 const noKeepAlive = meta && meta.ignoreKeepAlive;
105 const hasName = this.keepAliveTabsState.includes(name); 110 const hasName = this.keepAliveTabsState.includes(name);
@@ -113,9 +118,9 @@ class Tab extends VuexModule { @@ -113,9 +118,9 @@ class Tab extends VuexModule {
113 @Mutation 118 @Mutation
114 commitCloseTab(route: AppRouteRecordRaw | TabItem): void { 119 commitCloseTab(route: AppRouteRecordRaw | TabItem): void {
115 try { 120 try {
116 - const { path, name, meta: { affix } = {} } = route; 121 + const { fullPath, name, meta: { affix } = {} } = route;
117 if (affix) return; 122 if (affix) return;
118 - const index = this.tabsState.findIndex((item) => item.path === path); 123 + const index = this.tabsState.findIndex((item) => item.fullPath === fullPath);
119 index !== -1 && this.tabsState.splice(index, 1); 124 index !== -1 && this.tabsState.splice(index, 1);
120 125
121 if (unref(getOpenKeepAliveRef) && name) { 126 if (unref(getOpenKeepAliveRef) && name) {
@@ -153,7 +158,7 @@ class Tab extends VuexModule { @@ -153,7 +158,7 @@ class Tab extends VuexModule {
153 158
154 @Mutation 159 @Mutation
155 closeMultipleTab({ pathList, nameList }: { pathList: string[]; nameList: string[] }): void { 160 closeMultipleTab({ pathList, nameList }: { pathList: string[]; nameList: string[] }): void {
156 - this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.path)); 161 + this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath));
157 if (unref(getOpenKeepAliveRef) && nameList) { 162 if (unref(getOpenKeepAliveRef) && nameList) {
158 this.keepAliveTabsState = toRaw(this.keepAliveTabsState).filter( 163 this.keepAliveTabsState = toRaw(this.keepAliveTabsState).filter(
159 (item) => !nameList.includes(item as string) 164 (item) => !nameList.includes(item as string)
@@ -172,7 +177,7 @@ class Tab extends VuexModule { @@ -172,7 +177,7 @@ class Tab extends VuexModule {
172 for (const item of leftTabs) { 177 for (const item of leftTabs) {
173 const affix = item.meta ? item.meta.affix : false; 178 const affix = item.meta ? item.meta.affix : false;
174 if (!affix) { 179 if (!affix) {
175 - pathList.push(item.path); 180 + pathList.push(item.fullPath);
176 nameList.push(item.name as string); 181 nameList.push(item.name as string);
177 } 182 }
178 } 183 }
@@ -181,13 +186,19 @@ class Tab extends VuexModule { @@ -181,13 +186,19 @@ class Tab extends VuexModule {
181 } 186 }
182 187
183 @Action 188 @Action
184 - addTabByPathAction(to: AppRouteRecordRaw): void {  
185 - to && this.commitAddTab((to as unknown) as AppRouteRecordRaw); 189 + addTabByPathAction(): void {
  190 + const toRoute = getCurrentTo();
  191 + if (!toRoute) return;
  192 + const { meta } = toRoute;
  193 + if (meta && meta.affix) {
  194 + return;
  195 + }
  196 + this.commitAddTab((toRoute as unknown) as AppRouteRecordRaw);
186 } 197 }
187 198
188 @Action 199 @Action
189 closeRightTabAction(route: AppRouteRecordRaw | TabItem): void { 200 closeRightTabAction(route: AppRouteRecordRaw | TabItem): void {
190 - const index = this.tabsState.findIndex((item) => item.path === route.path); 201 + const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath);
191 202
192 if (index >= 0 && index < this.tabsState.length - 1) { 203 if (index >= 0 && index < this.tabsState.length - 1) {
193 const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length); 204 const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length);
@@ -197,7 +208,7 @@ class Tab extends VuexModule { @@ -197,7 +208,7 @@ class Tab extends VuexModule {
197 for (const item of rightTabs) { 208 for (const item of rightTabs) {
198 const affix = item.meta ? item.meta.affix : false; 209 const affix = item.meta ? item.meta.affix : false;
199 if (!affix) { 210 if (!affix) {
200 - pathList.push(item.path); 211 + pathList.push(item.fullPath);
201 nameList.push(item.name as string); 212 nameList.push(item.name as string);
202 } 213 }
203 } 214 }
@@ -207,16 +218,16 @@ class Tab extends VuexModule { @@ -207,16 +218,16 @@ class Tab extends VuexModule {
207 218
208 @Action 219 @Action
209 closeOtherTabAction(route: AppRouteRecordRaw | TabItem): void { 220 closeOtherTabAction(route: AppRouteRecordRaw | TabItem): void {
210 - const closePathList = this.tabsState.map((item) => item.path); 221 + const closePathList = this.tabsState.map((item) => item.fullPath);
211 const pathList: string[] = []; 222 const pathList: string[] = [];
212 const nameList: string[] = []; 223 const nameList: string[] = [];
213 closePathList.forEach((path) => { 224 closePathList.forEach((path) => {
214 - if (path !== route.path) { 225 + if (path !== route.fullPath) {
215 const closeItem = this.tabsState.find((item) => item.path === path); 226 const closeItem = this.tabsState.find((item) => item.path === path);
216 if (!closeItem) return; 227 if (!closeItem) return;
217 const affix = closeItem.meta ? closeItem.meta.affix : false; 228 const affix = closeItem.meta ? closeItem.meta.affix : false;
218 if (!affix) { 229 if (!affix) {
219 - pathList.push(closeItem.path); 230 + pathList.push(closeItem.fullPath);
220 nameList.push(closeItem.name as string); 231 nameList.push(closeItem.name as string);
221 } 232 }
222 } 233 }
src/types/source.d.ts
1 declare module 'ant-design-vue/es/locale/zh_CN'; 1 declare module 'ant-design-vue/es/locale/zh_CN';
2 -declare module 'vue-draggable-resizable'; 2 +declare module 'globby!/@/router/routes/modules/**/*.@(ts)';
  3 +declare module 'globby!/@/router/menus/modules/**/*.@(ts)';
  4 +
3 declare const React: string; 5 declare const React: string;
4 declare module '*.bmp' { 6 declare module '*.bmp' {
5 const src: string; 7 const src: string;
src/utils/eventHub.ts
@@ -16,9 +16,6 @@ class EventHub { @@ -16,9 +16,6 @@ class EventHub {
16 16
17 emit(eventName: string, data?: any) { 17 emit(eventName: string, data?: any) {
18 if (this.cache[eventName] === undefined) return; 18 if (this.cache[eventName] === undefined) return;
19 - console.log('======================');  
20 - console.log(this.cache, eventName);  
21 - console.log('======================');  
22 this.cache[eventName].forEach((fn) => fn(data)); 19 this.cache[eventName].forEach((fn) => fn(data));
23 } 20 }
24 off(eventName: string, fn: (data: any) => void) { 21 off(eventName: string, fn: (data: any) => void) {
src/utils/helper/menuHelper.ts
@@ -4,7 +4,6 @@ import type { MenuModule, Menu, AppRouteRecordRaw } from &#39;/@/router/types&#39;; @@ -4,7 +4,6 @@ import type { MenuModule, Menu, AppRouteRecordRaw } from &#39;/@/router/types&#39;;
4 import { findPath, forEach, treeMap, treeToList } from './treeHelper'; 4 import { findPath, forEach, treeMap, treeToList } from './treeHelper';
5 import { cloneDeep } from 'lodash-es'; 5 import { cloneDeep } from 'lodash-es';
6 6
7 -//  
8 export function getAllParentPath(treeData: any[], path: string) { 7 export function getAllParentPath(treeData: any[], path: string) {
9 const menuList = findPath(treeData, (n) => n.path === path) as Menu[]; 8 const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
10 return (menuList || []).map((item) => item.path); 9 return (menuList || []).map((item) => item.path);
@@ -14,6 +13,7 @@ export function flatMenus(menus: Menu[]) { @@ -14,6 +13,7 @@ export function flatMenus(menus: Menu[]) {
14 return treeToList(menus); 13 return treeToList(menus);
15 } 14 }
16 15
  16 +// 拼接父级路径
17 function joinParentPath(list: any, node: any) { 17 function joinParentPath(list: any, node: any) {
18 let allPaths = getAllParentPath(list, node.path); 18 let allPaths = getAllParentPath(list, node.path);
19 19
@@ -26,7 +26,6 @@ function joinParentPath(list: any, node: any) { @@ -26,7 +26,6 @@ function joinParentPath(list: any, node: any) {
26 parentPath += /^\//.test(p) ? p : `/${p}`; 26 parentPath += /^\//.test(p) ? p : `/${p}`;
27 }); 27 });
28 } 28 }
29 -  
30 node.path = `${parentPath}${/^\//.test(node.path) ? node.path : `/${node.path}`}`.replace( 29 node.path = `${parentPath}${/^\//.test(node.path) ? node.path : `/${node.path}`}`.replace(
31 /\/\//g, 30 /\/\//g,
32 '/' 31 '/'
@@ -34,6 +33,7 @@ function joinParentPath(list: any, node: any) { @@ -34,6 +33,7 @@ function joinParentPath(list: any, node: any) {
34 return node; 33 return node;
35 } 34 }
36 35
  36 +// 解析菜单模块
37 export function transformMenuModule(menuModule: MenuModule): Menu { 37 export function transformMenuModule(menuModule: MenuModule): Menu {
38 const { menu } = menuModule; 38 const { menu } = menuModule;
39 39
src/utils/helper/routeHelper.ts
1 import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types'; 1 import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types';
2 -import type { RouteRecordRaw } from 'vue-router'; 2 +import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
3 3
4 import { appStore } from '/@/store/modules/app'; 4 import { appStore } from '/@/store/modules/app';
5 import { tabStore } from '/@/store/modules/tab'; 5 import { tabStore } from '/@/store/modules/tab';
6 import { createRouter, createWebHashHistory } from 'vue-router'; 6 import { createRouter, createWebHashHistory } from 'vue-router';
7 import { toRaw } from 'vue'; 7 import { toRaw } from 'vue';
8 import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant'; 8 import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant';
  9 +
  10 +let currentTo: RouteLocationNormalized | null = null;
  11 +
  12 +export function getCurrentTo() {
  13 + return currentTo;
  14 +}
  15 +
  16 +export function setCurrentTo(to: RouteLocationNormalized) {
  17 + currentTo = to;
  18 +}
  19 +// 转化路由模块
  20 +// 将多级转成2层。keepAlive问题
9 export function genRouteModule(moduleList: AppRouteModule[]) { 21 export function genRouteModule(moduleList: AppRouteModule[]) {
10 const ret: AppRouteRecordRaw[] = []; 22 const ret: AppRouteRecordRaw[] = [];
11 for (const routeMod of moduleList) { 23 for (const routeMod of moduleList) {
@@ -27,6 +39,7 @@ export function genRouteModule(moduleList: AppRouteModule[]) { @@ -27,6 +39,7 @@ export function genRouteModule(moduleList: AppRouteModule[]) {
27 return ret as RouteRecordRaw[]; 39 return ret as RouteRecordRaw[];
28 } 40 }
29 41
  42 +// 动态引入
30 function asyncImportRoute(routes: AppRouteRecordRaw[]) { 43 function asyncImportRoute(routes: AppRouteRecordRaw[]) {
31 routes.forEach((item) => { 44 routes.forEach((item) => {
32 const { component, children } = item; 45 const { component, children } = item;
@@ -37,6 +50,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[]) { @@ -37,6 +50,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[]) {
37 }); 50 });
38 } 51 }
39 52
  53 +// 将后台对象转成路由对象
40 export function transformObjToRoute(routeList: AppRouteModule[]) { 54 export function transformObjToRoute(routeList: AppRouteModule[]) {
41 routeList.forEach((route) => { 55 routeList.forEach((route) => {
42 asyncImportRoute(route.routes); 56 asyncImportRoute(route.routes);
@@ -48,6 +62,7 @@ export function transformObjToRoute(routeList: AppRouteModule[]) { @@ -48,6 +62,7 @@ export function transformObjToRoute(routeList: AppRouteModule[]) {
48 return routeList; 62 return routeList;
49 } 63 }
50 64
  65 +//
51 export function getIsOpenTab(toPath: string) { 66 export function getIsOpenTab(toPath: string) {
52 const { openKeepAlive, multiTabsSetting: { show } = {} } = appStore.getProjectConfig; 67 const { openKeepAlive, multiTabsSetting: { show } = {} } = appStore.getProjectConfig;
53 68
@@ -57,3 +72,13 @@ export function getIsOpenTab(toPath: string) { @@ -57,3 +72,13 @@ export function getIsOpenTab(toPath: string) {
57 } 72 }
58 return false; 73 return false;
59 } 74 }
  75 +
  76 +export function getParams(data: any = {}) {
  77 + const { params = {} } = data;
  78 + let ret = '';
  79 + Object.keys(params).forEach((key) => {
  80 + const p = params[key];
  81 + ret += `/${p}`;
  82 + });
  83 + return ret;
  84 +}
src/views/demo/feat/tab-params/index.vue 0 → 100644
  1 +<template>
  2 + <div class="p-4"> Current Param : {{ params }} </div>
  3 +</template>
  4 +<script lang="ts">
  5 + import { computed, defineComponent, unref } from 'vue';
  6 + import { useRouter } from 'vue-router';
  7 + export default defineComponent({
  8 + setup() {
  9 + const { currentRoute } = useRouter();
  10 + return {
  11 + params: computed(() => {
  12 + return unref(currentRoute).params;
  13 + }),
  14 + };
  15 + },
  16 + });
  17 +</script>
src/views/sys/redirect/index.vue
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <div /> 2 <div />
3 </template> 3 </template>
4 <script lang="ts"> 4 <script lang="ts">
5 - import { defineComponent, onBeforeMount, unref } from 'vue'; 5 + import { defineComponent, unref } from 'vue';
6 6
7 import { appStore } from '/@/store/modules/app'; 7 import { appStore } from '/@/store/modules/app';
8 8
@@ -11,21 +11,19 @@ @@ -11,21 +11,19 @@
11 name: 'Redirect', 11 name: 'Redirect',
12 setup() { 12 setup() {
13 const { currentRoute, replace } = useRouter(); 13 const { currentRoute, replace } = useRouter();
14 - onBeforeMount(() => {  
15 - const { params, query } = unref(currentRoute);  
16 - const { path } = params;  
17 - const _path = Array.isArray(path) ? path.join('/') : path;  
18 - replace({  
19 - path: '/' + _path,  
20 - query,  
21 - });  
22 - const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;  
23 - if (openRouterTransition && openPageLoading) {  
24 - setTimeout(() => {  
25 - appStore.setPageLoadingAction(false);  
26 - }, 0);  
27 - } 14 + const { params, query } = unref(currentRoute);
  15 + const { path } = params;
  16 + const _path = Array.isArray(path) ? path.join('/') : path;
  17 + replace({
  18 + path: '/' + _path,
  19 + query,
28 }); 20 });
  21 + const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
  22 + if (openRouterTransition && openPageLoading) {
  23 + setTimeout(() => {
  24 + appStore.setPageLoadingAction(false);
  25 + }, 0);
  26 + }
29 return {}; 27 return {};
30 }, 28 },
31 }); 29 });
vite.config.ts
@@ -71,7 +71,7 @@ const viteConfig: UserConfig = { @@ -71,7 +71,7 @@ const viteConfig: UserConfig = {
71 * boolean | 'terser' | 'esbuild' 71 * boolean | 'terser' | 'esbuild'
72 * @default 'terser' 72 * @default 'terser'
73 */ 73 */
74 - minify: isDevFn() ? false : 'terser', 74 + minify: 'terser',
75 /** 75 /**
76 * 基本公共路径 76 * 基本公共路径
77 * @default '/' 77 * @default '/'