Commit ee1c3498587951a6a4cc0b49edb9dacf3f2af5c3
1 parent
780a8a67
fix(menu): improve menu logic, fix #461
Showing
13 changed files
with
66 additions
and
33 deletions
CHANGELOG.zh_CN.md
src/components/Application/src/AppDarkModeToggle.vue
... | ... | @@ -3,7 +3,6 @@ |
3 | 3 | v-if="getShowDarkModeToggle" |
4 | 4 | :class="[ |
5 | 5 | prefixCls, |
6 | - `${prefixCls}--${size}`, | |
7 | 6 | { |
8 | 7 | [`${prefixCls}--dark`]: isDark, |
9 | 8 | }, |
... | ... | @@ -30,13 +29,13 @@ |
30 | 29 | export default defineComponent({ |
31 | 30 | name: 'DarkModeToggle', |
32 | 31 | components: { SvgIcon }, |
33 | - props: { | |
34 | - size: { | |
35 | - type: String, | |
36 | - default: 'default', | |
37 | - validate: (val) => ['default', 'large'].includes(val), | |
38 | - }, | |
39 | - }, | |
32 | + // props: { | |
33 | + // size: { | |
34 | + // type: String, | |
35 | + // default: 'default', | |
36 | + // validate: (val) => ['default', 'large'].includes(val), | |
37 | + // }, | |
38 | + // }, | |
40 | 39 | setup() { |
41 | 40 | const { prefixCls } = useDesign('dark-mode-toggle'); |
42 | 41 | const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting(); |
... | ... | @@ -97,15 +96,15 @@ |
97 | 96 | } |
98 | 97 | } |
99 | 98 | |
100 | - &--large { | |
101 | - width: 72px; | |
102 | - height: 34px; | |
103 | - padding: 0 10px; | |
99 | + // &--large { | |
100 | + // width: 70px; | |
101 | + // height: 34px; | |
102 | + // padding: 0 10px; | |
104 | 103 | |
105 | - .@{prefix-cls}-inner { | |
106 | - width: 26px; | |
107 | - height: 26px; | |
108 | - } | |
109 | - } | |
104 | + // .@{prefix-cls}-inner { | |
105 | + // width: 26px; | |
106 | + // height: 26px; | |
107 | + // } | |
108 | + // } | |
110 | 109 | } |
111 | 110 | </style> | ... | ... |
src/components/Icon/src/index.vue
... | ... | @@ -24,8 +24,6 @@ |
24 | 24 | import Iconify from '@purge-icons/generated'; |
25 | 25 | import { isString } from '/@/utils/is'; |
26 | 26 | import { propTypes } from '/@/utils/propTypes'; |
27 | - import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | |
28 | - import { ThemeEnum } from '/@/enums/appEnum'; | |
29 | 27 | |
30 | 28 | const SVG_END_WITH_FLAG = '|svg'; |
31 | 29 | export default defineComponent({ |
... | ... | @@ -46,8 +44,6 @@ |
46 | 44 | setup(props) { |
47 | 45 | const elRef = ref<ElRef>(null); |
48 | 46 | |
49 | - const { getDarkMode } = useRootSetting(); | |
50 | - | |
51 | 47 | const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG)); |
52 | 48 | const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, '')); |
53 | 49 | const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`); |
... | ... | @@ -85,7 +81,7 @@ |
85 | 81 | |
86 | 82 | return { |
87 | 83 | fontSize: `${fs}px`, |
88 | - color: color || (unref(getDarkMode) === ThemeEnum.DARK ? '#fff' : '#303133'), | |
84 | + color: color, | |
89 | 85 | display: 'inline-flex', |
90 | 86 | }; |
91 | 87 | } | ... | ... |
src/components/SimpleMenu/src/SimpleMenu.vue
1 | 1 | <template> |
2 | 2 | <Menu |
3 | 3 | v-bind="getBindValues" |
4 | - @select="handleSelect" | |
5 | 4 | :activeName="activeName" |
6 | 5 | :openNames="getOpenKeys" |
7 | 6 | :class="prefixCls" |
8 | 7 | :activeSubMenuNames="activeSubMenuNames" |
8 | + @select="handleSelect" | |
9 | + @open-change="handleOpenChange" | |
9 | 10 | > |
10 | 11 | <template v-for="item in items" :key="item.path"> |
11 | 12 | <SimpleSubMenu |
... | ... | @@ -53,6 +54,7 @@ |
53 | 54 | beforeClickFn: { |
54 | 55 | type: Function as PropType<(key: string) => Promise<boolean>>, |
55 | 56 | }, |
57 | + isSplitMenu: propTypes.bool, | |
56 | 58 | }, |
57 | 59 | emits: ['menuClick'], |
58 | 60 | setup(props, { attrs, emit }) { |
... | ... | @@ -94,6 +96,9 @@ |
94 | 96 | watch( |
95 | 97 | () => props.items, |
96 | 98 | () => { |
99 | + if (!props.isSplitMenu) { | |
100 | + return; | |
101 | + } | |
97 | 102 | setOpenKeys(currentRoute.value.path); |
98 | 103 | }, |
99 | 104 | { flush: 'post' } |
... | ... | @@ -135,11 +140,17 @@ |
135 | 140 | menuState.activeName = key; |
136 | 141 | } |
137 | 142 | |
143 | + function handleOpenChange(v) { | |
144 | + console.log('======================'); | |
145 | + console.log(v); | |
146 | + console.log('======================'); | |
147 | + } | |
138 | 148 | return { |
139 | 149 | prefixCls, |
140 | 150 | getBindValues, |
141 | 151 | handleSelect, |
142 | 152 | getOpenKeys, |
153 | + handleOpenChange, | |
143 | 154 | ...toRefs(menuState), |
144 | 155 | }; |
145 | 156 | }, | ... | ... |
src/components/SimpleMenu/src/components/Menu.vue
... | ... | @@ -138,6 +138,15 @@ |
138 | 138 | }); |
139 | 139 | emit('select', name); |
140 | 140 | }); |
141 | + | |
142 | + rootMenuEmitter.on('open-name-change', ({ name, opened }) => { | |
143 | + if (opened && !openedNames.value.includes(name)) { | |
144 | + openedNames.value.push(name); | |
145 | + } else if (!opened) { | |
146 | + const index = openedNames.value.findIndex((item) => item === name); | |
147 | + index !== -1 && openedNames.value.splice(index, 1); | |
148 | + } | |
149 | + }); | |
141 | 150 | }); |
142 | 151 | |
143 | 152 | return { getClass, openedNames }; | ... | ... |
src/components/SimpleMenu/src/components/MenuItem.vue
... | ... | @@ -66,11 +66,16 @@ |
66 | 66 | |
67 | 67 | function handleClickItem() { |
68 | 68 | const { disabled } = props; |
69 | - if (disabled) return; | |
69 | + if (disabled) { | |
70 | + return; | |
71 | + } | |
70 | 72 | |
71 | 73 | rootMenuEmitter.emit('on-menu-item-select', props.name); |
72 | - if (unref(getCollapse)) return; | |
74 | + if (unref(getCollapse)) { | |
75 | + return; | |
76 | + } | |
73 | 77 | const { uidList } = getParentList(); |
78 | + | |
74 | 79 | rootMenuEmitter.emit('on-update-opened', { |
75 | 80 | opend: false, |
76 | 81 | parent: instance?.parent, | ... | ... |
src/components/SimpleMenu/src/components/SubMenuItem.vue
... | ... | @@ -43,8 +43,9 @@ |
43 | 43 | :class="`${prefixCls}-submenu-title-icon`" |
44 | 44 | /> |
45 | 45 | </div> |
46 | - <template #content> | |
47 | - <div v-bind="getEvents(true)" v-show="opened"> | |
46 | + <!-- eslint-disable-next-line --> | |
47 | + <template #content v-show="opened"> | |
48 | + <div v-bind="getEvents(true)"> | |
48 | 49 | <ul :class="[prefixCls, `${prefixCls}-${getTheme}`, `${prefixCls}-popup`]"> |
49 | 50 | <slot></slot> |
50 | 51 | </ul> |
... | ... | @@ -78,7 +79,7 @@ |
78 | 79 | import { isBoolean, isObject } from '/@/utils/is'; |
79 | 80 | import Mitt from '/@/utils/mitt'; |
80 | 81 | |
81 | - const DELAY = 250; | |
82 | + const DELAY = 200; | |
82 | 83 | export default defineComponent({ |
83 | 84 | name: 'SubMenu', |
84 | 85 | components: { |
... | ... | @@ -189,6 +190,7 @@ |
189 | 190 | const { disabled } = props; |
190 | 191 | if (disabled || unref(getCollapse)) return; |
191 | 192 | const opened = state.opened; |
193 | + | |
192 | 194 | if (unref(getAccordion)) { |
193 | 195 | const { uidList } = getParentList(); |
194 | 196 | rootMenuEmitter.emit('on-update-opened', { |
... | ... | @@ -196,6 +198,11 @@ |
196 | 198 | parent: instance?.parent, |
197 | 199 | uidList: uidList, |
198 | 200 | }); |
201 | + } else { | |
202 | + rootMenuEmitter.emit('open-name-change', { | |
203 | + name: props.name, | |
204 | + opened: !opened, | |
205 | + }); | |
199 | 206 | } |
200 | 207 | state.opened = !opened; |
201 | 208 | } | ... | ... |
src/components/SimpleMenu/src/useOpenKeys.ts
... | ... | @@ -8,7 +8,7 @@ import { uniq } from 'lodash-es'; |
8 | 8 | import { getAllParentPath } from '/@/router/helper/menuHelper'; |
9 | 9 | |
10 | 10 | import { useTimeoutFn } from '/@/hooks/core/useTimeout'; |
11 | -import { useDebounce } from '../../../hooks/core/useDebounce'; | |
11 | +import { useDebounce } from '/@/hooks/core/useDebounce'; | |
12 | 12 | |
13 | 13 | export function useOpenKeys( |
14 | 14 | menuState: MenuState, | ... | ... |
src/layouts/default/menu/index.vue
... | ... | @@ -49,6 +49,7 @@ |
49 | 49 | getAccordion, |
50 | 50 | getIsHorizontal, |
51 | 51 | getIsSidebarType, |
52 | + getSplit, | |
52 | 53 | } = useMenuSetting(); |
53 | 54 | const { getShowLogo } = useRootSetting(); |
54 | 55 | |
... | ... | @@ -144,7 +145,7 @@ |
144 | 145 | // console.log(menus); |
145 | 146 | if (!menus || !menus.length) return null; |
146 | 147 | return !props.isHorizontal ? ( |
147 | - <SimpleMenu {...menuProps} items={menus} /> | |
148 | + <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} /> | |
148 | 149 | ) : ( |
149 | 150 | <BasicMenu |
150 | 151 | {...menuProps} | ... | ... |
src/layouts/default/setting/SettingDrawer.tsx
... | ... | @@ -408,7 +408,7 @@ export default defineComponent({ |
408 | 408 | wrapClassName="setting-drawer" |
409 | 409 | > |
410 | 410 | {unref(getShowDarkModeToggle) && <Divider>{() => t('layout.setting.darkMode')}</Divider>} |
411 | - {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" size="large" />} | |
411 | + {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" />} | |
412 | 412 | <Divider>{() => t('layout.setting.navMode')}</Divider> |
413 | 413 | {renderSidebar()} |
414 | 414 | <Divider>{() => t('layout.setting.sysTheme')}</Divider> | ... | ... |
src/layouts/default/tabs/index.less
src/router/routes/modules/demo/charts.ts