Commit 66acb21edda3fcac61849c7c03c6b396992d8d06

Authored by vben
1 parent 8b3a4d37

perf: perf menu mini style

src/components/Menu/src/BasicMenu.tsx
@@ -145,6 +145,15 @@ export default defineComponent({ @@ -145,6 +145,15 @@ export default defineComponent({
145 resetKeys(); 145 resetKeys();
146 } 146 }
147 } 147 }
  148 +
  149 + const showTitle = computed(() => {
  150 + if (!props.isAppMenu) return true;
  151 + if (!props.collapsedShowTitle) {
  152 + return !menuStore.getCollapsedState;
  153 + }
  154 + return true;
  155 + });
  156 +
148 // render menu item 157 // render menu item
149 function renderMenuItem(menuList?: MenuType[], index = 1) { 158 function renderMenuItem(menuList?: MenuType[], index = 1) {
150 if (!menuList) { 159 if (!menuList) {
@@ -153,13 +162,6 @@ export default defineComponent({ @@ -153,13 +162,6 @@ export default defineComponent({
153 const { appendClass } = props; 162 const { appendClass } = props;
154 const levelCls = `basic-menu-item__level${index} ${menuState.theme} `; 163 const levelCls = `basic-menu-item__level${index} ${menuState.theme} `;
155 164
156 - const showTitle = computed(() => {  
157 - if (!props.isAppMenu) return true;  
158 - if (!props.collapsedShowTitle) {  
159 - return !menuStore.getCollapsedState;  
160 - }  
161 - return true;  
162 - });  
163 return menuList.map((menu) => { 165 return menuList.map((menu) => {
164 if (!menu) { 166 if (!menu) {
165 return null; 167 return null;
@@ -249,7 +251,7 @@ export default defineComponent({ @@ -249,7 +251,7 @@ export default defineComponent({
249 return mode === MenuModeEnum.HORIZONTAL ? ( 251 return mode === MenuModeEnum.HORIZONTAL ? (
250 renderMenu() 252 renderMenu()
251 ) : ( 253 ) : (
252 - <section class={`basic-menu-wrap`}> 254 + <section class={[`basic-menu-wrap`, !unref(showTitle) && 'hide-title']}>
253 {getSlot(slots, 'header')} 255 {getSlot(slots, 'header')}
254 <SearchInput 256 <SearchInput
255 class={!props.search ? 'hidden' : ''} 257 class={!props.search ? 'hidden' : ''}
src/components/Menu/src/index.less
1 @import (reference) '../../../design/index.less'; 1 @import (reference) '../../../design/index.less';
2 2
  3 +.active-style() {
  4 + color: @white;
  5 + background: linear-gradient(
  6 + 118deg,
  7 + rgba(@primary-color, 0.7),
  8 + rgba(@primary-color, 1)
  9 + ) !important;
  10 + border-radius: 2px;
  11 + box-shadow: 0 0 4px 1px rgba(@primary-color, 0.7);
  12 +}
  13 +
3 .active-menu-style() { 14 .active-menu-style() {
4 .ant-menu-item-selected, 15 .ant-menu-item-selected,
5 .ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected { 16 .ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
6 - background: linear-gradient(  
7 - 118deg,  
8 - rgba(@primary-color, 0.7),  
9 - rgba(@primary-color, 1)  
10 - ) !important;  
11 - border-radius: 2px;  
12 - box-shadow: 0 0 4px 1px rgba(@primary-color, 0.7); 17 + .active-style();
13 } 18 }
14 } 19 }
15 20
16 .basic-menu { 21 .basic-menu {
  22 + width: 100%;
  23 +
17 &.collapsed-show-title.ant-menu-inline-collapsed { 24 &.collapsed-show-title.ant-menu-inline-collapsed {
  25 + .basic-menu-item__level1 {
  26 + padding: 2px 0;
  27 + }
  28 +
18 & > li > .ant-menu-submenu-title { 29 & > li > .ant-menu-submenu-title {
19 display: flex; 30 display: flex;
20 margin-top: 12px; 31 margin-top: 12px;
21 font-size: 12px; 32 font-size: 12px;
22 flex-direction: column; 33 flex-direction: column;
  34 + line-height: 24px;
23 } 35 }
24 36
25 & > li[role='menuitem']:not(.ant-menu-submenu) { 37 & > li[role='menuitem']:not(.ant-menu-submenu) {
@@ -106,7 +118,7 @@ @@ -106,7 +118,7 @@
106 .ant-menu-submenu-open, 118 .ant-menu-submenu-open,
107 .ant-menu-item-selected, 119 .ant-menu-item-selected,
108 .ant-menu-submenu-selected { 120 .ant-menu-submenu-selected {
109 - color: @primary-color; 121 + color: @white !important;
110 border-bottom: 3px solid @primary-color; 122 border-bottom: 3px solid @primary-color;
111 } 123 }
112 124
@@ -115,7 +127,7 @@ @@ -115,7 +127,7 @@
115 .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, 127 .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open,
116 .ant-menu-submenu-active, 128 .ant-menu-submenu-active,
117 .ant-menu-submenu-title:hover { 129 .ant-menu-submenu-title:hover {
118 - color: @primary-color; 130 + color: @white !important;
119 border-bottom: 3px solid @primary-color; 131 border-bottom: 3px solid @primary-color;
120 } 132 }
121 133
@@ -194,12 +206,12 @@ @@ -194,12 +206,12 @@
194 } 206 }
195 207
196 .basic-menu-item__level1 { 208 .basic-menu-item__level1 {
  209 + margin-bottom: 0;
  210 +
197 > .ant-menu-sub > li { 211 > .ant-menu-sub > li {
198 background-color: @sub-menu-item-dark-bg-color; 212 background-color: @sub-menu-item-dark-bg-color;
199 } 213 }
200 214
201 - margin-bottom: 0;  
202 -  
203 &.top-active-menu { 215 &.top-active-menu {
204 color: @white; 216 color: @white;
205 background: @top-menu-active-bg-color; 217 background: @top-menu-active-bg-color;
@@ -236,6 +248,11 @@ @@ -236,6 +248,11 @@
236 } 248 }
237 249
238 &.ant-menu-inline-collapsed { 250 &.ant-menu-inline-collapsed {
  251 + .ant-menu-submenu-selected,
  252 + .ant-menu-item-selected {
  253 + .active-style();
  254 + }
  255 +
239 .ant-menu-item-selected { 256 .ant-menu-item-selected {
240 background: unset !important; 257 background: unset !important;
241 box-shadow: none; 258 box-shadow: none;
src/components/Menu/src/props.ts
@@ -31,7 +31,7 @@ export const basicProps = { @@ -31,7 +31,7 @@ export const basicProps = {
31 }, 31 },
32 // 菜单组件的mode属性 32 // 菜单组件的mode属性
33 mode: { 33 mode: {
34 - type: String as PropType<string>, 34 + type: String as PropType<MenuModeEnum>,
35 default: MenuModeEnum.INLINE, 35 default: MenuModeEnum.INLINE,
36 }, 36 },
37 type: { 37 type: {
src/enums/appEnum.ts
  1 +export const SIDE_BAR_MINI_WIDTH = 58;
  2 +export const SIDE_BAR_SHOW_TIT_MINI_WIDTH = 80;
  3 +
1 export enum ContentEnum { 4 export enum ContentEnum {
2 // auto width 5 // auto width
3 FULL = 'full', 6 FULL = 'full',
src/hooks/core/useSetting.ts
@@ -4,6 +4,9 @@ import getProjectSetting from &#39;/@/settings/projectSetting&#39;; @@ -4,6 +4,9 @@ import getProjectSetting from &#39;/@/settings/projectSetting&#39;;
4 4
5 import { getGlobEnvConfig, isDevMode } from '/@/utils/env'; 5 import { getGlobEnvConfig, isDevMode } from '/@/utils/env';
6 import { getShortName } from '../../../build/getShortName'; 6 import { getShortName } from '../../../build/getShortName';
  7 +import { warn } from '/@/utils/log';
  8 +
  9 +const reg = /[a-zA-Z\_]*/;
7 10
8 const ENV_NAME = getShortName(import.meta.env); 11 const ENV_NAME = getShortName(import.meta.env);
9 const ENV = ((isDevMode() 12 const ENV = ((isDevMode()
@@ -16,6 +19,10 @@ const { @@ -16,6 +19,10 @@ const {
16 VITE_GLOB_API_URL_PREFIX, 19 VITE_GLOB_API_URL_PREFIX,
17 } = ENV; 20 } = ENV;
18 21
  22 +if (!reg.test(VITE_GLOB_APP_SHORT_NAME)) {
  23 + warn(`VITE_GLOB_APP_SHORT_NAME 变量只能是字符/下划线,请在环境变量中修改并重新运行。`);
  24 +}
  25 +
19 export const useSetting = (): SettingWrap => { 26 export const useSetting = (): SettingWrap => {
20 // Take global configuration 27 // Take global configuration
21 const glob: Readonly<GlobConfig> = { 28 const glob: Readonly<GlobConfig> = {
src/layouts/default/LayoutSideBar.tsx
@@ -10,8 +10,10 @@ import darkImg from &#39;/@/assets/images/sidebar/dark.png&#39;; @@ -10,8 +10,10 @@ import darkImg from &#39;/@/assets/images/sidebar/dark.png&#39;;
10 import lightImg from '/@/assets/images/sidebar/light.png'; 10 import lightImg from '/@/assets/images/sidebar/light.png';
11 import { appStore } from '/@/store/modules/app'; 11 import { appStore } from '/@/store/modules/app';
12 import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum'; 12 import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum';
  13 +import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
13 import { useDebounce } from '/@/hooks/core/useDebounce'; 14 import { useDebounce } from '/@/hooks/core/useDebounce';
14 import LayoutMenu from './LayoutMenu'; 15 import LayoutMenu from './LayoutMenu';
  16 +
15 export default defineComponent({ 17 export default defineComponent({
16 name: 'DefaultLayoutSideBar', 18 name: 'DefaultLayoutSideBar',
17 setup() { 19 setup() {
@@ -25,6 +27,13 @@ export default defineComponent({ @@ -25,6 +27,13 @@ export default defineComponent({
25 return appStore.getProjectConfig; 27 return appStore.getProjectConfig;
26 }); 28 });
27 29
  30 + const getMiniWidth = computed(() => {
  31 + const {
  32 + menuSetting: { collapsedShowTitle },
  33 + } = unref(getProjectConfigRef);
  34 + return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
  35 + });
  36 +
28 // 根据展开状态设置背景图片 37 // 根据展开状态设置背景图片
29 const getStyle = computed((): any => { 38 const getStyle = computed((): any => {
30 // const collapse = unref(collapseRef); 39 // const collapse = unref(collapseRef);
@@ -62,7 +71,7 @@ export default defineComponent({ @@ -62,7 +71,7 @@ export default defineComponent({
62 innerE = innerE || window.event; 71 innerE = innerE || window.event;
63 // let tarnameb = innerE.target || innerE.srcElement; 72 // let tarnameb = innerE.target || innerE.srcElement;
64 const maxT = 600; 73 const maxT = 600;
65 - const minT = 80; 74 + const minT = unref(getMiniWidth);
66 iT < 0 && (iT = 0); 75 iT < 0 && (iT = 0);
67 iT > maxT && (iT = maxT); 76 iT > maxT && (iT = maxT);
68 iT < minT && (iT = minT); 77 iT < minT && (iT = minT);
@@ -80,13 +89,13 @@ export default defineComponent({ @@ -80,13 +89,13 @@ export default defineComponent({
80 const width = parseInt(wrap.style.width); 89 const width = parseInt(wrap.style.width);
81 menuStore.commitDragStartState(false); 90 menuStore.commitDragStartState(false);
82 if (!menuStore.getCollapsedState) { 91 if (!menuStore.getCollapsedState) {
83 - if (width > 100) { 92 + if (width > unref(getMiniWidth) + 20) {
84 setMenuWidth(width); 93 setMenuWidth(width);
85 } else { 94 } else {
86 menuStore.commitCollapsedState(true); 95 menuStore.commitCollapsedState(true);
87 } 96 }
88 } else { 97 } else {
89 - if (width > 80) { 98 + if (width > unref(getMiniWidth)) {
90 setMenuWidth(width); 99 setMenuWidth(width);
91 menuStore.commitCollapsedState(false); 100 menuStore.commitCollapsedState(false);
92 } 101 }
@@ -135,13 +144,13 @@ export default defineComponent({ @@ -135,13 +144,13 @@ export default defineComponent({
135 144
136 const getDragBarStyle = computed(() => { 145 const getDragBarStyle = computed(() => {
137 if (menuStore.getCollapsedState) { 146 if (menuStore.getCollapsedState) {
138 - return { left: '80px' }; 147 + return { left: `${unref(getMiniWidth)}px` };
139 } 148 }
140 return {}; 149 return {};
141 }); 150 });
142 151
143 const getCollapsedWidth = computed(() => { 152 const getCollapsedWidth = computed(() => {
144 - return unref(brokenRef) ? 0 : 80; 153 + return unref(brokenRef) ? 0 : unref(getMiniWidth);
145 }); 154 });
146 155
147 function renderDragLine() { 156 function renderDragLine() {
src/layouts/default/index.less
@@ -422,3 +422,17 @@ @@ -422,3 +422,17 @@
422 height: 30px; 422 height: 30px;
423 line-height: 30px; 423 line-height: 30px;
424 } 424 }
  425 +
  426 +.hide-title {
  427 + .ant-menu-inline-collapsed > .ant-menu-item,
  428 + .ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item,
  429 + .ant-menu-inline-collapsed
  430 + > .ant-menu-item-group
  431 + > .ant-menu-item-group-list
  432 + > .ant-menu-submenu
  433 + > .ant-menu-submenu-title,
  434 + .ant-menu-inline-collapsed > .ant-menu-submenu > .ant-menu-submenu-title {
  435 + padding-right: 20px !important;
  436 + padding-left: 20px !important;
  437 + }
  438 +}
src/store/modules/permission.ts
@@ -19,7 +19,8 @@ import { genRouteModule, transformObjToRoute } from &#39;/@/utils/helper/routeHelper @@ -19,7 +19,8 @@ import { genRouteModule, transformObjToRoute } from &#39;/@/utils/helper/routeHelper
19 import { transformRouteToMenu } from '/@/utils/helper/menuHelper'; 19 import { transformRouteToMenu } from '/@/utils/helper/menuHelper';
20 20
21 import { useMessage } from '/@/hooks/web/useMessage'; 21 import { useMessage } from '/@/hooks/web/useMessage';
22 -import { warn } from 'vue'; 22 +import { warn } from '/@/utils/log';
  23 +
23 const { createMessage } = useMessage(); 24 const { createMessage } = useMessage();
24 const NAME = 'permission'; 25 const NAME = 'permission';
25 hotModuleUnregisterModule(NAME); 26 hotModuleUnregisterModule(NAME);
src/utils/log.ts 0 → 100644
  1 +const projectName = import.meta.env.VITE_GLOB_APP_TITLE;
  2 +export function warn(message: string) {
  3 + console.warn(`[${projectName} warn]:${message}`);
  4 +}
vite.config.ts
@@ -80,7 +80,7 @@ const viteConfig: UserConfig = { @@ -80,7 +80,7 @@ const viteConfig: UserConfig = {
80 * boolean | 'terser' | 'esbuild' 80 * boolean | 'terser' | 'esbuild'
81 * @default 'terser' 81 * @default 'terser'
82 */ 82 */
83 - minify: 'terser', 83 + minify: isDevFn() ? 'esbuild' : 'terser',
84 /** 84 /**
85 * 基本公共路径 85 * 基本公共路径
86 * @default '/' 86 * @default '/'