Commit 2f12556d26ba386d9dca2ecf8a88e3764abab870
1 parent
5737e478
fix: fix the top menu adaptive failure
Showing
7 changed files
with
70 additions
and
22 deletions
src/App.vue
@@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
18 | import { useSetting } from '/@/hooks/core/useSetting'; | 18 | import { useSetting } from '/@/hooks/core/useSetting'; |
19 | 19 | ||
20 | moment.locale('zh-cn'); | 20 | moment.locale('zh-cn'); |
21 | + | ||
21 | export default defineComponent({ | 22 | export default defineComponent({ |
22 | name: 'App', | 23 | name: 'App', |
23 | components: { ConfigProvider }, | 24 | components: { ConfigProvider }, |
src/components/Menu/src/BasicMenu.tsx
@@ -45,7 +45,8 @@ export default defineComponent({ | @@ -45,7 +45,8 @@ export default defineComponent({ | ||
45 | menuState, | 45 | menuState, |
46 | toRef(props, 'items'), | 46 | toRef(props, 'items'), |
47 | toRef(props, 'flatItems'), | 47 | toRef(props, 'flatItems'), |
48 | - toRef(props, 'isAppMenu') | 48 | + toRef(props, 'isAppMenu'), |
49 | + toRef(props, 'mode') | ||
49 | ); | 50 | ); |
50 | 51 | ||
51 | const getOpenKeys = computed(() => { | 52 | const getOpenKeys = computed(() => { |
src/components/Menu/src/useOpenKeys.ts
1 | +import { MenuModeEnum } from '/@/enums/menuEnum'; | ||
1 | import type { Menu as MenuType } from '/@/router/types'; | 2 | import type { Menu as MenuType } from '/@/router/types'; |
2 | import type { MenuState } from './types'; | 3 | import type { MenuState } from './types'; |
3 | import type { Ref } from 'vue'; | 4 | import type { Ref } from 'vue'; |
@@ -10,7 +11,8 @@ export function useOpenKeys( | @@ -10,7 +11,8 @@ export function useOpenKeys( | ||
10 | menuState: MenuState, | 11 | menuState: MenuState, |
11 | menus: Ref<MenuType[]>, | 12 | menus: Ref<MenuType[]>, |
12 | flatMenusRef: Ref<MenuType[]>, | 13 | flatMenusRef: Ref<MenuType[]>, |
13 | - isAppMenu: Ref<boolean> | 14 | + isAppMenu: Ref<boolean>, |
15 | + mode: Ref<MenuModeEnum> | ||
14 | ) { | 16 | ) { |
15 | /** | 17 | /** |
16 | * @description:设置展开 | 18 | * @description:设置展开 |
@@ -28,21 +30,25 @@ export function useOpenKeys( | @@ -28,21 +30,25 @@ export function useOpenKeys( | ||
28 | } | 30 | } |
29 | 31 | ||
30 | function handleOpenChange(openKeys: string[]) { | 32 | function handleOpenChange(openKeys: string[]) { |
31 | - const rootSubMenuKeys: string[] = []; | ||
32 | - for (const { children, path } of unref(menus)) { | ||
33 | - if (children && children.length > 0) { | ||
34 | - rootSubMenuKeys.push(path); | 33 | + if (unref(mode) === MenuModeEnum.HORIZONTAL) { |
34 | + menuState.openKeys = openKeys; | ||
35 | + } else { | ||
36 | + const rootSubMenuKeys: string[] = []; | ||
37 | + for (const { children, path } of unref(menus)) { | ||
38 | + if (children && children.length > 0) { | ||
39 | + rootSubMenuKeys.push(path); | ||
40 | + } | ||
35 | } | 41 | } |
36 | - } | ||
37 | - if (!menuStore.getCollapsedState || !unref(isAppMenu)) { | ||
38 | - const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1); | ||
39 | - if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) { | ||
40 | - menuState.openKeys = openKeys; | 42 | + if (!menuStore.getCollapsedState || !unref(isAppMenu)) { |
43 | + const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1); | ||
44 | + if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) { | ||
45 | + menuState.openKeys = openKeys; | ||
46 | + } else { | ||
47 | + menuState.openKeys = latestOpenKey ? [latestOpenKey] : []; | ||
48 | + } | ||
41 | } else { | 49 | } else { |
42 | - menuState.openKeys = latestOpenKey ? [latestOpenKey] : []; | 50 | + menuState.collapsedOpenKeys = openKeys; |
43 | } | 51 | } |
44 | - } else { | ||
45 | - menuState.collapsedOpenKeys = openKeys; | ||
46 | } | 52 | } |
47 | } | 53 | } |
48 | return { setOpenKeys, resetKeys, handleOpenChange }; | 54 | return { setOpenKeys, resetKeys, handleOpenChange }; |
src/components/Modal/src/BasicModal.tsx
@@ -217,7 +217,11 @@ export default defineComponent({ | @@ -217,7 +217,11 @@ export default defineComponent({ | ||
217 | const uuid = buildUUID(); | 217 | const uuid = buildUUID(); |
218 | emit('register', modalMethods, uuid); | 218 | emit('register', modalMethods, uuid); |
219 | return () => ( | 219 | return () => ( |
220 | - <Modal onCancel={handleCancel} {...{ ...attrs, ...props, ...unref(getProps) }}> | 220 | + <Modal |
221 | + onCancel={handleCancel} | ||
222 | + {...{ ...attrs, ...props, ...unref(getProps) }} | ||
223 | + getContainer={() => document.querySelector('.default-layout__main')} | ||
224 | + > | ||
221 | {{ | 225 | {{ |
222 | ...extendSlots(slots, ['default']), | 226 | ...extendSlots(slots, ['default']), |
223 | default: () => renderContent(), | 227 | default: () => renderContent(), |
src/hooks/event/useWindowSize.ts
@@ -4,6 +4,7 @@ import { tryOnMounted, tryOnUnmounted } from '/@/utils/helper/vueHelper'; | @@ -4,6 +4,7 @@ import { tryOnMounted, tryOnUnmounted } from '/@/utils/helper/vueHelper'; | ||
4 | import { ref } from 'vue'; | 4 | import { ref } from 'vue'; |
5 | 5 | ||
6 | import { useDebounce } from '/@/hooks/core/useDebounce'; | 6 | import { useDebounce } from '/@/hooks/core/useDebounce'; |
7 | +import { CancelFn } from '../core/types'; | ||
7 | 8 | ||
8 | interface WindowSizeOptions { | 9 | interface WindowSizeOptions { |
9 | once?: boolean; | 10 | once?: boolean; |
@@ -11,7 +12,7 @@ interface WindowSizeOptions { | @@ -11,7 +12,7 @@ interface WindowSizeOptions { | ||
11 | listenerOptions?: AddEventListenerOptions | boolean; | 12 | listenerOptions?: AddEventListenerOptions | boolean; |
12 | } | 13 | } |
13 | 14 | ||
14 | -export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions): void { | 15 | +export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions): CancelFn { |
15 | let handler = () => { | 16 | let handler = () => { |
16 | fn(); | 17 | fn(); |
17 | }; | 18 | }; |
@@ -19,6 +20,9 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp | @@ -19,6 +20,9 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp | ||
19 | handler = handleSize; | 20 | handler = handleSize; |
20 | 21 | ||
21 | tryOnMounted(() => { | 22 | tryOnMounted(() => { |
23 | + if (options && options.immediate) { | ||
24 | + handler(); | ||
25 | + } | ||
22 | window.addEventListener('resize', handler); | 26 | window.addEventListener('resize', handler); |
23 | }); | 27 | }); |
24 | 28 | ||
@@ -26,6 +30,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp | @@ -26,6 +30,7 @@ export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOp | ||
26 | window.removeEventListener('resize', handler); | 30 | window.removeEventListener('resize', handler); |
27 | cancel(); | 31 | cancel(); |
28 | }); | 32 | }); |
33 | + return cancel; | ||
29 | } | 34 | } |
30 | 35 | ||
31 | export const useWindowSize = (wait = 150, options?: WindowSizeOptions) => { | 36 | export const useWindowSize = (wait = 150, options?: WindowSizeOptions) => { |
src/layouts/default/LayoutHeader.tsx
1 | -import { defineComponent, unref, computed } from 'vue'; | 1 | +import { defineComponent, unref, computed, ref } from 'vue'; |
2 | import { Layout, Tooltip, Badge } from 'ant-design-vue'; | 2 | import { Layout, Tooltip, Badge } from 'ant-design-vue'; |
3 | import Logo from '/@/layouts/Logo.vue'; | 3 | import Logo from '/@/layouts/Logo.vue'; |
4 | import UserDropdown from './UserDropdown'; | 4 | import UserDropdown from './UserDropdown'; |
@@ -21,17 +21,44 @@ import LockAction from './actions/LockActionItem'; | @@ -21,17 +21,44 @@ import LockAction from './actions/LockActionItem'; | ||
21 | import { useModal } from '/@/components/Modal/index'; | 21 | import { useModal } from '/@/components/Modal/index'; |
22 | import { errorStore } from '/@/store/modules/error'; | 22 | import { errorStore } from '/@/store/modules/error'; |
23 | import { useGo } from '/@/hooks/web/usePage'; | 23 | import { useGo } from '/@/hooks/web/usePage'; |
24 | +import { useWindowSizeFn } from '/@/hooks/event/useWindowSize'; | ||
24 | 25 | ||
25 | export default defineComponent({ | 26 | export default defineComponent({ |
26 | name: 'DefaultLayoutHeader', | 27 | name: 'DefaultLayoutHeader', |
27 | setup() { | 28 | setup() { |
29 | + const widthRef = ref(200); | ||
28 | const { refreshPage } = useTabs(); | 30 | const { refreshPage } = useTabs(); |
29 | const [register, { openModal }] = useModal(); | 31 | const [register, { openModal }] = useModal(); |
30 | const { toggleFullscreen, isFullscreenRef } = useFullscreen(); | 32 | const { toggleFullscreen, isFullscreenRef } = useFullscreen(); |
33 | + | ||
31 | const go = useGo(); | 34 | const go = useGo(); |
32 | const getProjectConfigRef = computed(() => { | 35 | const getProjectConfigRef = computed(() => { |
33 | return appStore.getProjectConfig; | 36 | return appStore.getProjectConfig; |
34 | }); | 37 | }); |
38 | + const showTopMenu = computed(() => { | ||
39 | + const getProjectConfig = unref(getProjectConfigRef); | ||
40 | + const { | ||
41 | + menuSetting: { mode, split: splitMenu }, | ||
42 | + } = getProjectConfig; | ||
43 | + return mode === MenuModeEnum.HORIZONTAL || splitMenu; | ||
44 | + }); | ||
45 | + | ||
46 | + let logoEl: Element | null; | ||
47 | + useWindowSizeFn( | ||
48 | + () => { | ||
49 | + if (!unref(showTopMenu)) return; | ||
50 | + let width = 0; | ||
51 | + if (!logoEl) { | ||
52 | + logoEl = document.querySelector('.layout-header__logo'); | ||
53 | + } | ||
54 | + if (logoEl) { | ||
55 | + width += logoEl.clientWidth; | ||
56 | + } | ||
57 | + widthRef.value = width + 60; | ||
58 | + }, | ||
59 | + 200, | ||
60 | + { immediate: true } | ||
61 | + ); | ||
35 | 62 | ||
36 | function goToGithub() { | 63 | function goToGithub() { |
37 | window.open(GITHUB_URL, '__blank'); | 64 | window.open(GITHUB_URL, '__blank'); |
@@ -64,6 +91,7 @@ export default defineComponent({ | @@ -64,6 +91,7 @@ export default defineComponent({ | ||
64 | } = getProjectConfig; | 91 | } = getProjectConfig; |
65 | 92 | ||
66 | const isSidebarType = menuType === MenuTypeEnum.SIDEBAR; | 93 | const isSidebarType = menuType === MenuTypeEnum.SIDEBAR; |
94 | + const width = unref(widthRef); | ||
67 | return ( | 95 | return ( |
68 | <Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}> | 96 | <Layout.Header class={['layout-header', 'flex p-0 px-4 ', unref(headerClass)]}> |
69 | {() => ( | 97 | {() => ( |
@@ -74,8 +102,11 @@ export default defineComponent({ | @@ -74,8 +102,11 @@ export default defineComponent({ | ||
74 | {mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && ( | 102 | {mode !== MenuModeEnum.HORIZONTAL && showBreadCrumb && !splitMenu && ( |
75 | <LayoutBreadcrumb /> | 103 | <LayoutBreadcrumb /> |
76 | )} | 104 | )} |
77 | - {(mode === MenuModeEnum.HORIZONTAL || splitMenu) && ( | ||
78 | - <div class={[`layout-header__menu `, `justify-${topMenuAlign}`]}> | 105 | + {unref(showTopMenu) && ( |
106 | + <div | ||
107 | + class={[`layout-header__menu `, `justify-${topMenuAlign}`]} | ||
108 | + style={{ width: `calc(100% - ${unref(width)}px)` }} | ||
109 | + > | ||
79 | <LayoutMenu | 110 | <LayoutMenu |
80 | theme={headerTheme} | 111 | theme={headerTheme} |
81 | splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE} | 112 | splitType={splitMenu ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE} |
src/layouts/default/index.less
@@ -206,7 +206,7 @@ | @@ -206,7 +206,7 @@ | ||
206 | &__content { | 206 | &__content { |
207 | flex-grow: 1; | 207 | flex-grow: 1; |
208 | display: flex; | 208 | display: flex; |
209 | - justify-content: center; | 209 | + // justify-content: center; |
210 | align-items: center; | 210 | align-items: center; |
211 | } | 211 | } |
212 | 212 | ||
@@ -346,11 +346,11 @@ | @@ -346,11 +346,11 @@ | ||
346 | } | 346 | } |
347 | 347 | ||
348 | &__menu { | 348 | &__menu { |
349 | - display: flex; | 349 | + // display: flex; |
350 | margin-left: 20px; | 350 | margin-left: 20px; |
351 | overflow: hidden; | 351 | overflow: hidden; |
352 | align-items: center; | 352 | align-items: center; |
353 | - flex-grow: 1; | 353 | + // flex-grow: 1; |
354 | } | 354 | } |
355 | 355 | ||
356 | &__user-dropdown { | 356 | &__user-dropdown { |