Commit 4f6b65b8a1b7e694718b4aa42aced1e59e90ec9e

Authored by vben
1 parent 58f988a7

feat(trigger): add trigger config

CHANGELOG.zh_CN.md
1 1 ## Wip
2 2  
  3 +### ✨ Features
  4 +
  5 +- 菜单 trigger 可以选择位置
  6 +- 增加富文本嵌入表单的示例
  7 +- 表单组件 schema 增加 `required`属性。简化配置
  8 +- openModal 和 openDrawer 第二个参数可以代替`transferModalData`传参到内部
  9 +
3 10 ### ⚡ Performance Improvements
4 11  
5 12 - 菜单性能继续优化,更流畅
6 13 - 优化懒加载组件及示例
  14 +- layout 样式微调
7 15  
8 16 ### 🎫 Chores
9 17  
... ...
package.json
... ... @@ -28,6 +28,7 @@
28 28 "echarts": "^4.9.0",
29 29 "lodash-es": "^4.17.15",
30 30 "mockjs": "^1.1.0",
  31 + "moment": "^2.29.1",
31 32 "nprogress": "^0.2.0",
32 33 "path-to-regexp": "^6.2.0",
33 34 "qrcode": "^1.4.4",
... ...
src/App.vue
... ... @@ -11,7 +11,7 @@
11 11  
12 12 import zhCN from 'ant-design-vue/es/locale/zh_CN';
13 13 import moment from 'moment';
14   - import 'moment/locale/zh-cn';
  14 + import 'moment/dist/locale/zh-cn';
15 15  
16 16 import { useConfigProvider, useInitAppConfigStore, useListenerNetWork } from './useApp';
17 17 import { useLockPage } from '/@/hooks/web/useLockPage';
... ...
src/components/Menu/src/BasicMenu.tsx
... ... @@ -73,7 +73,7 @@ export default defineComponent({
73 73 offset += 46;
74 74 }
75 75 return {
76   - height: `calc(100% - ${offset - 10}px)`,
  76 + height: `calc(100% - ${offset - 12}px)`,
77 77 position: 'relative',
78 78 overflowY: 'auto',
79 79 };
... ...
src/components/Menu/src/MenuContent.tsx
... ... @@ -32,7 +32,7 @@ export default defineComponent({
32 32 * @description: 渲染图标
33 33 */
34 34 function renderIcon(icon: string) {
35   - return icon ? <Icon icon={icon} size={18} class="mr-1 menu-item-icon" /> : null;
  35 + return icon ? <Icon icon={icon} size={18} class="menu-item-icon" /> : null;
36 36 }
37 37  
38 38 return () => {
... ...
src/components/Menu/src/index.less
... ... @@ -41,6 +41,7 @@
41 41 font-size: 12px;
42 42 flex-direction: column;
43 43 align-items: center;
  44 + line-height: 24px;
44 45 }
45 46  
46 47 & > li > .ant-menu-submenu-title {
... ... @@ -183,9 +184,17 @@
183 184 transition: unset;
184 185 }
185 186  
  187 + &:not(.basic-menu__sidebar-hor).ant-menu-inline-collapsed {
  188 + .basic-menu-item__level1 {
  189 + > div {
  190 + align-items: center;
  191 + }
  192 + }
  193 + }
  194 +
186 195 &.ant-menu-dark:not(.basic-menu__sidebar-hor):not(.basic-menu__second) {
187 196 // Reset menu item row height
188   - .ant-menu-item,
  197 + .ant-menu-item:not(.basic-menu-item__level1),
189 198 .ant-menu-sub.ant-menu-inline > .ant-menu-item,
190 199 .ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title {
191 200 height: @app-menu-item-height;
... ...
src/enums/menuEnum.ts
... ... @@ -17,6 +17,16 @@ export enum MenuThemeEnum {
17 17 LIGHT = 'light',
18 18 }
19 19  
  20 +// 折叠触发器位置
  21 +export enum TriggerEnum {
  22 + // 不显示
  23 + NONE = 'NONE',
  24 + // 菜单底部
  25 + FOOTER = 'FOOTER',
  26 + // 头部
  27 + HEADER = 'HEADER',
  28 +}
  29 +
20 30 export type Mode = 'vertical' | 'vertical-right' | 'horizontal' | 'inline';
21 31  
22 32 // menu mode
... ...
src/layouts/Logo.vue
1 1 <template>
2   - <div class="app-logo anticon" @click="handleGoHome" :style="wrapStyle">
  2 + <div class="app-logo anticon" :class="theme" @click="handleGoHome" :style="wrapStyle">
3 3 <img :src="logo" />
4 4 <div v-if="show" class="logo-title ml-2 ellipsis">{{ globSetting.title }}</div>
5 5 </div>
... ... @@ -26,6 +26,9 @@
26 26 type: Boolean as PropType<boolean>,
27 27 default: true,
28 28 },
  29 + theme: {
  30 + type: String,
  31 + },
29 32 },
30 33 setup(props) {
31 34 const showRef = ref<boolean>(!!props.showTitle);
... ... @@ -80,6 +83,9 @@
80 83 padding-left: 16px;
81 84 cursor: pointer;
82 85 // justify-content: center;
  86 + &.light {
  87 + border-bottom: 1px solid @border-color-base;
  88 + }
83 89  
84 90 .logo-title {
85 91 font-size: 18px;
... ...
src/layouts/default/LayoutContent.tsx
1 1 import { defineComponent } from 'vue';
2   -import { Layout } from 'ant-design-vue';
  2 +// import { Layout } from 'ant-design-vue';
3 3 // hooks
4 4  
5 5 import { ContentEnum } from '/@/enums/appEnum';
... ... @@ -13,9 +13,9 @@ export default defineComponent({
13 13 const { contentMode } = getProjectConfig;
14 14 const wrapClass = contentMode === ContentEnum.FULL ? 'full' : 'fixed';
15 15 return (
16   - <Layout.Content class={`layout-content ${wrapClass} `}>
17   - {() => <PageLayout />}
18   - </Layout.Content>
  16 + // <Layout.Content class={`layout-content ${wrapClass} `}>
  17 + <PageLayout class={`layout-content ${wrapClass} `} />
  18 + // </Layout.Content>
19 19 );
20 20 };
21 21 },
... ...
src/layouts/default/LayoutHeader.tsx
... ... @@ -6,6 +6,7 @@ import UserDropdown from &#39;./UserDropdown&#39;;
6 6 import LayoutMenu from './LayoutMenu';
7 7 import LayoutBreadcrumb from './LayoutBreadcrumb';
8 8 import LockAction from './actions/LockActionItem';
  9 +import LayoutTrigger from './LayoutTrigger';
9 10 import NoticeAction from './actions/notice/NoticeActionItem.vue';
10 11 import {
11 12 RedoOutlined,
... ... @@ -25,7 +26,7 @@ import { useModal } from &#39;/@/components/Modal/index&#39;;
25 26 import { appStore } from '/@/store/modules/app';
26 27 import { errorStore } from '/@/store/modules/error';
27 28  
28   -import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
  29 +import { MenuModeEnum, MenuSplitTyeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
29 30 import { GITHUB_URL } from '/@/settings/siteSetting';
30 31 export default defineComponent({
31 32 name: 'DefaultLayoutHeader',
... ... @@ -75,6 +76,13 @@ export default defineComponent({
75 76 return theme ? `layout-header__header--${theme}` : '';
76 77 });
77 78  
  79 + const showHeaderTrigger = computed(() => {
  80 + const { show, trigger, hidden } = unref(getProjectConfigRef).menuSetting;
  81 +
  82 + if (!show || !hidden) return false;
  83 + return trigger === TriggerEnum.HEADER;
  84 + });
  85 +
78 86 function handleToErrorList() {
79 87 errorStore.commitErrorListCountState(0);
80 88 push('/exception/error-log');
... ... @@ -92,6 +100,7 @@ export default defineComponent({
92 100 const {
93 101 useErrorHandle,
94 102 showLogo,
  103 + multiTabsSetting: { show: showTab },
95 104 headerSetting: {
96 105 theme: headerTheme,
97 106 useLockPage,
... ... @@ -114,11 +123,17 @@ export default defineComponent({
114 123 {() => (
115 124 <>
116 125 <div class="layout-header__content ">
117   - {showLogo && !isSidebarType && <Logo class={`layout-header__logo`} />}
118   -
119   - {mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
120   - <LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
  126 + {showLogo && !isSidebarType && (
  127 + <Logo class={`layout-header__logo`} theme={headerTheme} />
121 128 )}
  129 +
  130 + <div class="layout-header__left">
  131 + {unref(showHeaderTrigger) && <LayoutTrigger theme={headerTheme} sider={false} />}
  132 + {mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && (
  133 + <LayoutBreadcrumb showIcon={showBreadCrumbIcon} />
  134 + )}
  135 + </div>
  136 +
122 137 {unref(showTopMenu) && (
123 138 <div
124 139 class={[`layout-header__menu `]}
... ... @@ -193,7 +208,7 @@ export default defineComponent({
193 208 </Tooltip>
194 209 </div>
195 210 )}
196   - {showRedo && (
  211 + {showRedo && showTab && (
197 212 <Tooltip>
198 213 {{
199 214 title: () => '刷新',
... ...
src/layouts/default/LayoutMenu.tsx
... ... @@ -68,9 +68,6 @@ export default defineComponent({
68 68 return unref(getProjectConfigRef).menuSetting.mode === MenuModeEnum.HORIZONTAL;
69 69 });
70 70  
71   - onMounted(() => {
72   - genMenus();
73   - });
74 71 const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
75 72  
76 73 // watch(
... ... @@ -90,6 +87,7 @@ export default defineComponent({
90 87 immediate: true,
91 88 }
92 89 );
  90 +
93 91 watch(
94 92 [() => permissionStore.getLastBuildMenuTimeState, permissionStore.getBackMenuListState],
95 93 () => {
... ... @@ -112,7 +110,7 @@ export default defineComponent({
112 110 if (!children) {
113 111 appStore.commitProjectConfigState({
114 112 menuSetting: {
115   - show: false,
  113 + hidden: false,
116 114 },
117 115 });
118 116 flatMenusRef.value = [];
... ... @@ -122,7 +120,7 @@ export default defineComponent({
122 120 const flatChildren = await getFlatChildrenMenus(children);
123 121 appStore.commitProjectConfigState({
124 122 menuSetting: {
125   - show: true,
  123 + hidden: true,
126 124 },
127 125 });
128 126 flatMenusRef.value = flatChildren;
... ... @@ -193,6 +191,10 @@ export default defineComponent({
193 191 );
194 192 });
195 193  
  194 + onMounted(() => {
  195 + genMenus();
  196 + });
  197 +
196 198 return () => {
197 199 const {
198 200 showLogo,
... ... @@ -229,7 +231,11 @@ export default defineComponent({
229 231 {{
230 232 header: () =>
231 233 isShowLogo && (
232   - <Logo showTitle={!collapsed} class={[`layout-menu__logo`, themeData]} />
  234 + <Logo
  235 + showTitle={!collapsed}
  236 + class={[`layout-menu__logo`, themeData]}
  237 + theme={themeData}
  238 + />
233 239 ),
234 240 }}
235 241 </BasicMenu>
... ...
src/layouts/default/LayoutSideBar.tsx
1 1 import { computed, defineComponent, nextTick, onMounted, ref, unref } from 'vue';
2 2  
3 3 import { Layout } from 'ant-design-vue';
4   -import SideBarTrigger from './SideBarTrigger';
  4 +import LayoutTrigger from './LayoutTrigger';
5 5 import { menuStore } from '/@/store/modules/menu';
6 6  
7 7 // import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
8 8 // import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
9 9 // import lightImg from '/@/assets/images/sidebar/light.png';
10 10 import { appStore } from '/@/store/modules/app';
11   -import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
  11 +import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum';
12 12 import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
13 13 import { useDebounce } from '/@/hooks/core/useDebounce';
14 14 import LayoutMenu from './LayoutMenu';
... ... @@ -133,6 +133,25 @@ export default defineComponent({
133 133 return unref(brokenRef) ? 0 : unref(getMiniWidth);
134 134 });
135 135  
  136 + const showTrigger = computed(() => {
  137 + const {
  138 + menuSetting: { trigger },
  139 + } = unref(getProjectConfigRef);
  140 + return trigger !== TriggerEnum.NONE && trigger === TriggerEnum.FOOTER;
  141 + });
  142 +
  143 + function handleSiderClick(e: ChangeEvent) {
  144 + if (!e || !e.target || e.target.className !== 'basic-menu__content') return;
  145 +
  146 + const { collapsed, show } = appStore.getProjectConfig.menuSetting;
  147 + if (!collapsed || !show) return;
  148 + appStore.commitProjectConfigState({
  149 + menuSetting: {
  150 + collapsed: false,
  151 + },
  152 + });
  153 + }
  154 +
136 155 function renderDragLine() {
137 156 const { menuSetting: { hasDrag = true } = {} } = unref(getProjectConfigRef);
138 157 return (
... ... @@ -149,8 +168,22 @@ export default defineComponent({
149 168 menuSetting: { theme, split: splitMenu },
150 169 } = unref(getProjectConfigRef);
151 170 const { getCollapsedState, getMenuWidthState } = menuStore;
  171 +
  172 + const triggerDom = unref(showTrigger)
  173 + ? {
  174 + trigger: () => <LayoutTrigger />,
  175 + }
  176 + : {};
  177 +
  178 + const triggerAttr = unref(showTrigger)
  179 + ? {}
  180 + : {
  181 + trigger: null,
  182 + };
  183 +
152 184 return (
153 185 <Layout.Sider
  186 + onClick={handleSiderClick}
154 187 onCollapse={onCollapseChange}
155 188 breakpoint="md"
156 189 width={getMenuWidthState}
... ... @@ -161,9 +194,10 @@ export default defineComponent({
161 194 class="layout-sidebar"
162 195 ref={sideRef}
163 196 onBreakpoint={handleBreakpoint}
  197 + {...triggerAttr}
164 198 >
165 199 {{
166   - trigger: () => <SideBarTrigger />,
  200 + ...triggerDom,
167 201 default: () => (
168 202 <>
169 203 <LayoutMenu
... ...
src/layouts/default/LayoutTrigger.tsx 0 → 100644
  1 +import {
  2 + DoubleRightOutlined,
  3 + DoubleLeftOutlined,
  4 + MenuUnfoldOutlined,
  5 + MenuFoldOutlined,
  6 +} from '@ant-design/icons-vue';
  7 +import { defineComponent } from 'vue';
  8 +
  9 +// store
  10 +import { menuStore } from '/@/store/modules/menu';
  11 +
  12 +export default defineComponent({
  13 + name: 'LayoutTrigger',
  14 + props: {
  15 + sider: {
  16 + type: Boolean,
  17 + default: true,
  18 + },
  19 + theme: {
  20 + type: String,
  21 + },
  22 + },
  23 + setup(props) {
  24 + function toggleMenu() {
  25 + menuStore.commitCollapsedState(!menuStore.getCollapsedState);
  26 + }
  27 +
  28 + return () => {
  29 + const siderTrigger = menuStore.getCollapsedState ? (
  30 + <DoubleRightOutlined />
  31 + ) : (
  32 + <DoubleLeftOutlined />
  33 + );
  34 + if (props.sider) return siderTrigger;
  35 +
  36 + return (
  37 + <span class={['layout-trigger', props.theme]} onClick={toggleMenu}>
  38 + {menuStore.getCollapsedState ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
  39 + </span>
  40 + );
  41 + };
  42 + },
  43 +});
... ...
src/layouts/default/SideBarTrigger.tsx deleted 100644 → 0
1   -import { DoubleRightOutlined, DoubleLeftOutlined } from '@ant-design/icons-vue';
2   -import { defineComponent } from 'vue';
3   -
4   -// store
5   -import { menuStore } from '/@/store/modules/menu';
6   -
7   -export default defineComponent({
8   - name: 'SideBarTrigger',
9   - setup() {
10   - return () => (menuStore.getCollapsedState ? <DoubleRightOutlined /> : <DoubleLeftOutlined />);
11   - },
12   -});
src/layouts/default/index.less
... ... @@ -17,11 +17,10 @@
17 17 &__main {
18 18 position: relative;
19 19 height: 100%;
20   - // overflow: hidden;
21   - // overflow: auto;
22 20  
23 21 &.fixed {
24   - overflow: auto;
  22 + overflow-x: hidden;
  23 + overflow-y: auto;
25 24 }
26 25  
27 26 &.fixed.lock {
... ... @@ -373,9 +372,39 @@
373 372 }
374 373 }
375 374  
376   -.layout-breadcrumb {
377   - padding: 0 16px;
  375 +.layout-header__left {
378 376 flex-grow: 1;
  377 + display: flex;
  378 + align-items: center;
  379 +
  380 + .layout-trigger {
  381 + padding: 4px 10px 0 16px;
  382 + cursor: pointer;
  383 +
  384 + .anticon {
  385 + font-size: 17px;
  386 + }
  387 +
  388 + &.light {
  389 + &:hover {
  390 + background: @header-light-bg-hover-color;
  391 + }
  392 +
  393 + svg {
  394 + fill: #000;
  395 + }
  396 + }
  397 +
  398 + &.dark {
  399 + &:hover {
  400 + background: @header-dark-bg-hover-color;
  401 + }
  402 + }
  403 + }
  404 +
  405 + .layout-breadcrumb {
  406 + padding: 0 8px;
  407 + }
379 408 }
380 409  
381 410 .ant-layout-sider-trigger {
... ...
src/layouts/default/index.tsx
... ... @@ -73,7 +73,7 @@ export default defineComponent({
73 73 showSettingButton,
74 74 multiTabsSetting: { show: showTabs },
75 75 headerSetting: { fixed },
76   - menuSetting: { split, show },
  76 + menuSetting: { split, hidden },
77 77 } = unref(getProjectConfigRef);
78 78  
79 79 const fixedHeaderCls = fixed
... ... @@ -82,7 +82,7 @@ export default defineComponent({
82 82  
83 83 const { isLock } = getLockInfo;
84 84  
85   - const showSideBar = split ? show : true;
  85 + const showSideBar = split ? hidden : true;
86 86 return (
87 87 <Layout class="default-layout relative">
88 88 {() => (
... ... @@ -107,9 +107,7 @@ export default defineComponent({
107 107 unref(showHeaderRef) && <LayoutHeader />}
108 108  
109 109 {showTabs && !unref(getFullContent) && (
110   - <Layout.Header class={`default-layout__tabs`}>
111   - {() => <MultipleTabs />}
112   - </Layout.Header>
  110 + <MultipleTabs class={`default-layout__tabs`} />
113 111 )}
114 112  
115 113 {useOpenBackTop && <BackTop target={getTarget} />}
... ...
src/layouts/default/setting/SettingDrawer.tsx
... ... @@ -2,7 +2,13 @@ import { defineComponent, computed, unref, ref } from &#39;vue&#39;;
2 2 import { BasicDrawer } from '/@/components/Drawer/index';
3 3 import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
4 4 import Button from '/@/components/Button/index.vue';
5   -import { MenuModeEnum, MenuTypeEnum, MenuThemeEnum, TopMenuAlignEnum } from '/@/enums/menuEnum';
  5 +import {
  6 + MenuModeEnum,
  7 + MenuTypeEnum,
  8 + MenuThemeEnum,
  9 + TopMenuAlignEnum,
  10 + TriggerEnum,
  11 +} from '/@/enums/menuEnum';
6 12 import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum';
7 13 import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
8 14 import { appStore } from '/@/store/modules/app';
... ... @@ -23,41 +29,49 @@ const themeOptions = [
23 29 {
24 30 value: MenuThemeEnum.LIGHT,
25 31 label: '亮色',
26   - key: MenuThemeEnum.LIGHT,
27 32 },
28 33 {
29 34 value: MenuThemeEnum.DARK,
30 35 label: '暗色',
31   - key: MenuThemeEnum.DARK,
32 36 },
33 37 ];
34 38 const contentModeOptions = [
35 39 {
36 40 value: ContentEnum.FULL,
37 41 label: '流式',
38   - key: ContentEnum.FULL,
39 42 },
40 43 {
41 44 value: ContentEnum.FIXED,
42 45 label: '定宽',
43   - key: ContentEnum.FIXED,
44 46 },
45 47 ];
46 48 const topMenuAlignOptions = [
47 49 {
48 50 value: TopMenuAlignEnum.CENTER,
49 51 label: '居中',
50   - key: TopMenuAlignEnum.CENTER,
51 52 },
52 53 {
53 54 value: TopMenuAlignEnum.START,
54 55 label: '居左',
55   - key: TopMenuAlignEnum.START,
56 56 },
57 57 {
58 58 value: TopMenuAlignEnum.END,
59 59 label: '居右',
60   - key: TopMenuAlignEnum.END,
  60 + },
  61 +];
  62 +
  63 +const menuTriggerOptions = [
  64 + {
  65 + value: TriggerEnum.NONE,
  66 + label: '不显示',
  67 + },
  68 + {
  69 + value: TriggerEnum.FOOTER,
  70 + label: '底部',
  71 + },
  72 + {
  73 + value: TriggerEnum.HEADER,
  74 + label: '顶部',
61 75 },
62 76 ];
63 77  
... ... @@ -181,7 +195,7 @@ export default defineComponent({
181 195 baseHandler('splitMenu', e);
182 196 },
183 197 def: split,
184   - disabled: !unref(getShowMenuRef),
  198 + disabled: !unref(getShowMenuRef) || type !== MenuTypeEnum.MIX,
185 199 }),
186 200 renderSelectItem('顶栏主题', {
187 201 handler: (e) => {
... ... @@ -215,6 +229,7 @@ export default defineComponent({
215 229 menuWidth,
216 230 topMenuAlign,
217 231 collapsedShowTitle,
  232 + trigger,
218 233 } = {},
219 234 } = appStore.getProjectConfig;
220 235 return [
... ... @@ -262,6 +277,13 @@ export default defineComponent({
262 277 options: topMenuAlignOptions,
263 278 disabled: !unref(getShowHeaderRef),
264 279 }),
  280 + renderSelectItem('菜单折叠按钮', {
  281 + handler: (e) => {
  282 + baseHandler('menuTrigger', e);
  283 + },
  284 + def: trigger,
  285 + options: menuTriggerOptions,
  286 + }),
265 287 renderSelectItem('内容区域宽度', {
266 288 handler: (e) => {
267 289 baseHandler('contentMode', e);
... ... @@ -298,7 +320,7 @@ export default defineComponent({
298 320 disabled={!unref(getShowMenuRef)}
299 321 defaultValue={menuWidth}
300 322 formatter={(value: string) => `${parseInt(value)}px`}
301   - onChange={(e) => {
  323 + onChange={(e: any) => {
302 324 baseHandler('menuWidth', e);
303 325 }}
304 326 />
... ... @@ -424,13 +446,21 @@ export default defineComponent({
424 446 if (event === 'layout') {
425 447 const { mode, type, split } = value;
426 448 const splitOpt = split === undefined ? { split } : {};
  449 + let headerSetting = {};
  450 + if (type === MenuTypeEnum.TOP_MENU) {
  451 + headerSetting = {
  452 + theme: MenuThemeEnum.DARK,
  453 + };
  454 + }
427 455 config = {
428 456 menuSetting: {
429 457 mode,
430 458 type,
431 459 collapsed: false,
  460 + show: true,
432 461 ...splitOpt,
433 462 },
  463 + headerSetting,
434 464 };
435 465 }
436 466 if (event === 'hasDrag') {
... ... @@ -440,6 +470,13 @@ export default defineComponent({
440 470 },
441 471 };
442 472 }
  473 + if (event === 'menuTrigger') {
  474 + config = {
  475 + menuSetting: {
  476 + trigger: value,
  477 + },
  478 + };
  479 + }
443 480 if (event === 'openPageLoading') {
444 481 config = {
445 482 openPageLoading: value,
... ... @@ -647,7 +684,7 @@ export default defineComponent({
647 684 <Switch
648 685 {...opt}
649 686 disabled={disabled}
650   - onChange={(e) => {
  687 + onChange={(e: any) => {
651 688 handler && handler(e);
652 689 }}
653 690 checkedChildren="开"
... ...
src/settings/projectSetting.ts
1 1 import type { ProjectConfig } from '/@/types/config';
2 2  
3   -import { MenuTypeEnum, MenuThemeEnum, MenuModeEnum } from '/@/enums/menuEnum';
  3 +import { MenuTypeEnum, MenuThemeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum';
4 4 import { ContentEnum, PermissionModeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
5 5 import { primaryColor } from '../../build/config/lessModifyVars';
6 6 import { isProdMode } from '/@/utils/env';
... ... @@ -23,6 +23,7 @@ const setting: ProjectConfig = {
23 23 // 是否显示logo
24 24 showLogo: true,
25 25  
  26 + // 头部配置
26 27 headerSetting: {
27 28 fixed: true,
28 29 // 是否显示顶部
... ... @@ -50,8 +51,10 @@ const setting: ProjectConfig = {
50 51 collapsedShowTitle: false,
51 52 // 是否可拖拽
52 53 hasDrag: false,
53   - // 是否显示
  54 + // 是否显示 没有dom
54 55 show: true,
  56 + // 是否显示 有dom
  57 + hidden: false,
55 58 // 是否显示搜索框
56 59 showSearch: true,
57 60 // 菜单宽度
... ... @@ -67,7 +70,9 @@ const setting: ProjectConfig = {
67 70 // 顶部菜单布局
68 71 topMenuAlign: 'center',
69 72 // 折叠菜单时候隐藏搜索框
70   - collapsedShowSearch: true,
  73 + collapsedShowSearch: false,
  74 + // 折叠触发器的位置
  75 + trigger: TriggerEnum.HEADER,
71 76 },
72 77 // 消息配置
73 78 messageSetting: {
... ...
src/types/config.d.ts
1 1 // 左侧菜单, 顶部菜单
2   -import { MenuTypeEnum, MenuModeEnum, MenuThemeEnum } from '/@/enums/menuEnum';
  2 +import { MenuTypeEnum, MenuModeEnum, MenuThemeEnum, TriggerEnum } from '/@/enums/menuEnum';
3 3 import { ContentEnum, PermissionModeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
4 4  
5 5 export interface MessageSetting {
... ... @@ -15,6 +15,7 @@ export interface MenuSetting {
15 15 hasDrag: boolean;
16 16 showSearch: boolean;
17 17 show: boolean;
  18 + hidden: boolean;
18 19 split: boolean;
19 20 menuWidth: number;
20 21 mode: MenuModeEnum;
... ... @@ -22,6 +23,7 @@ export interface MenuSetting {
22 23 theme: MenuThemeEnum;
23 24 topMenuAlign: 'start' | 'center' | 'end';
24 25 collapsedShowSearch: boolean;
  26 + trigger: TriggerEnum;
25 27 }
26 28  
27 29 export interface MultiTabsSetting {
... ...
src/utils/helper/routeHelper.ts
... ... @@ -42,6 +42,7 @@ export function genRouteModule(moduleList: AppRouteModule[]) {
42 42 }
43 43  
44 44 // 动态引入
  45 +// TODO 错误写法
45 46 function asyncImportRoute(routes: AppRouteRecordRaw[]) {
46 47 routes.forEach((item) => {
47 48 let { component } = item;
... ...
vite.config.ts
... ... @@ -119,12 +119,7 @@ const viteConfig: UserConfig = {
119 119 },
120 120 // The package will be recompiled using rollup, and the new package compiled into the esm module specification will be put into node_modules/.vite_opt_cache
121 121 optimizeDeps: {
122   - include: [
123   - 'echarts/map/js/china',
124   - 'ant-design-vue/es/locale/zh_CN',
125   - '@ant-design/icons-vue',
126   - 'moment/locale/zh-cn',
127   - ],
  122 + include: ['echarts/map/js/china', 'ant-design-vue/es/locale/zh_CN', '@ant-design/icons-vue'],
128 123 },
129 124  
130 125 // Local cross-domain proxy
... ...
yarn.lock
... ... @@ -5513,7 +5513,7 @@ modify-values@^1.0.0:
5513 5513 resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
5514 5514 integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
5515 5515  
5516   -moment@^2.27.0:
  5516 +moment@^2.27.0, moment@^2.29.1:
5517 5517 version "2.29.1"
5518 5518 resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
5519 5519 integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
... ...