diff --git a/src/layouts/modules/global-menu/context/index.ts b/src/layouts/modules/global-menu/context/index.ts index b83b71b3..48313a34 100644 --- a/src/layouts/modules/global-menu/context/index.ts +++ b/src/layouts/modules/global-menu/context/index.ts @@ -3,6 +3,7 @@ import { useRoute } from 'vue-router'; import { useContext } from '@sa/hooks'; import type { RouteKey } from '@elegant-router/types'; import { useRouteStore } from '@/store/modules/route'; +import { useThemeStore } from '@/store/modules/theme'; import { useRouterPush } from '@/hooks/common/router'; export const [provideMixMenuContext, useMixMenuContext] = useContext('MixMenu', useMixMenu); @@ -10,6 +11,7 @@ export const [provideMixMenuContext, useMixMenuContext] = useContext('MixMenu', function useMixMenu() { const route = useRoute(); const routeStore = useRouteStore(); + const themeStore = useThemeStore(); const { selectedKey } = useMenu(); const { routerPushByKeyWithMetaQuery } = useRouterPush(); @@ -100,10 +102,46 @@ function useMixMenu() { () => secondLevelMenus.value.find(menu => menu.key === activeSecondLevelMenuKey.value)?.children || [] ); + const hasChildLevelMenus = computed(() => childLevelMenus.value.length > 0); + + function getDeepestLevelMenuKey(): RouteKey | null { + if (!secondLevelMenus.value.length || !themeStore.sider.autoSelectFirstMenu) { + return null; + } + + const secondLevelFirstMenu = secondLevelMenus.value[0]; + + if (!secondLevelFirstMenu) { + return null; + } + + function findDeepest(menu: App.Global.Menu): RouteKey { + if (!menu.children?.length) { + return menu.routeKey; + } + + return findDeepest(menu.children[0]); + } + + return findDeepest(secondLevelFirstMenu); + } + + function activeDeepestLevelMenuKey() { + const deepestLevelMenuKey = getDeepestLevelMenuKey(); + if (!deepestLevelMenuKey) return; + + // select the deepest second level menu + handleSelectSecondLevelMenu(deepestLevelMenuKey); + } + watch( () => route.name, () => { getActiveFirstLevelMenuKey(); + // if there are child level menus, get the active second level menu key + if (hasChildLevelMenus.value) { + getActiveSecondLevelMenuKey(); + } }, { immediate: true } ); @@ -121,7 +159,10 @@ function useMixMenu() { isActiveSecondLevelMenuHasChildren, handleSelectSecondLevelMenu, getActiveSecondLevelMenuKey, - childLevelMenus + childLevelMenus, + hasChildLevelMenus, + getDeepestLevelMenuKey, + activeDeepestLevelMenuKey }; } diff --git a/src/layouts/modules/global-menu/modules/top-hybrid-header-first.vue b/src/layouts/modules/global-menu/modules/top-hybrid-header-first.vue index 937e5933..b312f421 100644 --- a/src/layouts/modules/global-menu/modules/top-hybrid-header-first.vue +++ b/src/layouts/modules/global-menu/modules/top-hybrid-header-first.vue @@ -2,6 +2,7 @@ import { ref, watch } from 'vue'; import { useRoute } from 'vue-router'; import { SimpleScrollbar } from '@sa/materials'; +import type { RouteKey } from '@elegant-router/types'; import { GLOBAL_HEADER_MENU_ID, GLOBAL_SIDER_MENU_ID } from '@/constants/app'; import { useAppStore } from '@/store/modules/app'; import { useThemeStore } from '@/store/modules/theme'; @@ -18,12 +19,28 @@ const appStore = useAppStore(); const themeStore = useThemeStore(); const routeStore = useRouteStore(); const { routerPushByKeyWithMetaQuery } = useRouterPush(); -const { firstLevelMenus, secondLevelMenus, activeFirstLevelMenuKey, handleSelectFirstLevelMenu } = - useMixMenuContext('TopHybridHeaderFirst'); +const { + firstLevelMenus, + secondLevelMenus, + activeFirstLevelMenuKey, + handleSelectFirstLevelMenu, + activeDeepestLevelMenuKey +} = useMixMenuContext('TopHybridHeaderFirst'); const { selectedKey } = useMenu(); const expandedKeys = ref([]); +/** + * Handle first level menu select + * @param key RouteKey + */ +function handleSelectMenu(key: RouteKey) { + handleSelectFirstLevelMenu(key); + + // if there are second level menus, select the deepest one by default + activeDeepestLevelMenuKey(); +} + function updateExpandedKeys() { if (appStore.siderCollapse || !selectedKey.value) { expandedKeys.value = []; @@ -49,7 +66,7 @@ watch( :options="firstLevelMenus" :indent="18" responsive - @update:value="handleSelectFirstLevelMenu" + @update:value="handleSelectMenu" /> diff --git a/src/layouts/modules/global-menu/modules/top-hybrid-sidebar-first.vue b/src/layouts/modules/global-menu/modules/top-hybrid-sidebar-first.vue index ff037723..d12189e8 100644 --- a/src/layouts/modules/global-menu/modules/top-hybrid-sidebar-first.vue +++ b/src/layouts/modules/global-menu/modules/top-hybrid-sidebar-first.vue @@ -1,4 +1,5 @@