Преглед на файлове

feat: `autoActivateChild` support more layout mode (#5148)

Netfan преди 3 месеца
родител
ревизия
f6faeb034e

+ 2 - 0
packages/effects/layouts/src/basic/layout.vue

@@ -103,6 +103,7 @@ const {
 
 const {
   handleMenuSelect,
+  handleMenuOpen,
   headerActive,
   headerMenus,
   sidebarActive,
@@ -260,6 +261,7 @@ const headerSlots = computed(() => {
         :rounded="isMenuRounded"
         :theme="sidebarTheme"
         mode="vertical"
+        @open="handleMenuOpen"
         @select="handleMenuSelect"
       />
     </template>

+ 6 - 0
packages/effects/layouts/src/basic/menu/menu.vue

@@ -14,12 +14,17 @@ const props = withDefaults(defineProps<Props>(), {
 });
 
 const emit = defineEmits<{
+  open: [string, string[]];
   select: [string, string?];
 }>();
 
 function handleMenuSelect(key: string) {
   emit('select', key, props.mode);
 }
+
+function handleMenuOpen(key: string, path: string[]) {
+  emit('open', key, path);
+}
 </script>
 
 <template>
@@ -32,6 +37,7 @@ function handleMenuSelect(key: string) {
     :mode="mode"
     :rounded="rounded"
     :theme="theme"
+    @open="handleMenuOpen"
     @select="handleMenuSelect"
   />
 </template>

+ 24 - 1
packages/effects/layouts/src/basic/menu/use-mixed-menu.ts

@@ -15,7 +15,8 @@ function useMixedMenu() {
   const route = useRoute();
   const splitSideMenus = ref<MenuRecordRaw[]>([]);
   const rootMenuPath = ref<string>('');
-
+  /** 记录当前顶级菜单下哪个子菜单最后激活 */
+  const defaultSubMap = new Map<string, string>();
   const { isMixedNav } = usePreferences();
 
   const needSplit = computed(
@@ -86,6 +87,25 @@ function useMixedMenu() {
     splitSideMenus.value = rootMenu?.children ?? [];
     if (splitSideMenus.value.length === 0) {
       navigation(key);
+    } else if (rootMenu && preferences.sidebar.autoActivateChild) {
+      navigation(
+        defaultSubMap.has(rootMenu.path)
+          ? (defaultSubMap.get(rootMenu.path) as string)
+          : rootMenu.path,
+      );
+    }
+  };
+
+  /**
+   * 侧边菜单展开事件
+   * @param key 路由路径
+   * @param parentsPath 父级路径
+   */
+  const handleMenuOpen = (key: string, parentsPath: string[]) => {
+    if (parentsPath.length <= 1 && preferences.sidebar.autoActivateChild) {
+      navigation(
+        defaultSubMap.has(key) ? (defaultSubMap.get(key) as string) : key,
+      );
     }
   };
 
@@ -107,6 +127,8 @@ function useMixedMenu() {
     (path) => {
       const currentPath = (route?.meta?.activePath as string) ?? path;
       calcSideMenus(currentPath);
+      if (rootMenuPath.value)
+        defaultSubMap.set(rootMenuPath.value, currentPath);
     },
     { immediate: true },
   );
@@ -118,6 +140,7 @@ function useMixedMenu() {
 
   return {
     handleMenuSelect,
+    handleMenuOpen,
     headerActive,
     headerMenus,
     sidebarActive,

+ 5 - 1
packages/effects/layouts/src/widgets/preferences/blocks/layout/sidebar.vue

@@ -43,7 +43,11 @@ const sidebarExpandOnHover = defineModel<boolean>('sidebarExpandOnHover');
   <SwitchItem
     v-model="sidebarAutoActivateChild"
     :disabled="
-      !sidebarEnable || currentLayout !== 'sidebar-mixed-nav' || disabled
+      !sidebarEnable ||
+      !['sidebar-mixed-nav', 'mixed-nav', 'sidebar-nav'].includes(
+        currentLayout as string,
+      ) ||
+      disabled
     "
     :tip="$t('preferences.sidebar.autoActivateChildTip')"
   >