feat: auto activate subMenu on select root menu (#5147)
* feat: auto activate subMenu on click root menu * fix: prop name fixed * chore: test and docs update
This commit is contained in:
parent
22c1f86ca1
commit
2efb5b71c3
@ -217,6 +217,7 @@ const defaultPreferences: Preferences = {
|
|||||||
globalSearch: true,
|
globalSearch: true,
|
||||||
},
|
},
|
||||||
sidebar: {
|
sidebar: {
|
||||||
|
autoActivateChild: false,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
collapsedShowTitle: false,
|
collapsedShowTitle: false,
|
||||||
enable: true,
|
enable: true,
|
||||||
|
@ -240,6 +240,7 @@ const defaultPreferences: Preferences = {
|
|||||||
globalSearch: true,
|
globalSearch: true,
|
||||||
},
|
},
|
||||||
sidebar: {
|
sidebar: {
|
||||||
|
autoActivateChild: false,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
collapsedShowTitle: false,
|
collapsedShowTitle: false,
|
||||||
enable: true,
|
enable: true,
|
||||||
|
@ -65,6 +65,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
|
|||||||
"globalSearch": true,
|
"globalSearch": true,
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
|
"autoActivateChild": false,
|
||||||
"collapsed": false,
|
"collapsed": false,
|
||||||
"collapsedShowTitle": false,
|
"collapsedShowTitle": false,
|
||||||
"enable": true,
|
"enable": true,
|
||||||
|
@ -65,6 +65,7 @@ const defaultPreferences: Preferences = {
|
|||||||
globalSearch: true,
|
globalSearch: true,
|
||||||
},
|
},
|
||||||
sidebar: {
|
sidebar: {
|
||||||
|
autoActivateChild: false,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
collapsedShowTitle: false,
|
collapsedShowTitle: false,
|
||||||
enable: true,
|
enable: true,
|
||||||
|
@ -125,6 +125,8 @@ interface NavigationPreferences {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface SidebarPreferences {
|
interface SidebarPreferences {
|
||||||
|
/** 点击目录时自动激活子菜单 */
|
||||||
|
autoActivateChild: boolean;
|
||||||
/** 侧边栏是否折叠 */
|
/** 侧边栏是否折叠 */
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
/** 侧边栏折叠时,是否显示title */
|
/** 侧边栏折叠时,是否显示title */
|
||||||
|
@ -15,6 +15,9 @@ function useExtraMenu() {
|
|||||||
|
|
||||||
const menus = computed(() => accessStore.accessMenus);
|
const menus = computed(() => accessStore.accessMenus);
|
||||||
|
|
||||||
|
/** 记录当前顶级菜单下哪个子菜单最后激活 */
|
||||||
|
const defaultSubMap = new Map<string, string>();
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const extraMenus = ref<MenuRecordRaw[]>([]);
|
const extraMenus = ref<MenuRecordRaw[]>([]);
|
||||||
const sidebarExtraVisible = ref<boolean>(false);
|
const sidebarExtraVisible = ref<boolean>(false);
|
||||||
@ -32,6 +35,12 @@ function useExtraMenu() {
|
|||||||
sidebarExtraVisible.value = hasChildren;
|
sidebarExtraVisible.value = hasChildren;
|
||||||
if (!hasChildren) {
|
if (!hasChildren) {
|
||||||
await navigation(menu.path);
|
await navigation(menu.path);
|
||||||
|
} else if (preferences.sidebar.autoActivateChild) {
|
||||||
|
await navigation(
|
||||||
|
defaultSubMap.has(menu.path)
|
||||||
|
? (defaultSubMap.get(menu.path) as string)
|
||||||
|
: menu.path,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,6 +98,7 @@ function useExtraMenu() {
|
|||||||
menus.value,
|
menus.value,
|
||||||
currentPath,
|
currentPath,
|
||||||
);
|
);
|
||||||
|
if (rootMenuPath) defaultSubMap.set(rootMenuPath, currentPath);
|
||||||
extraActiveMenu.value = rootMenuPath ?? findMenu?.path ?? '';
|
extraActiveMenu.value = rootMenuPath ?? findMenu?.path ?? '';
|
||||||
extraMenus.value = rootMenu?.children ?? [];
|
extraMenus.value = rootMenu?.children ?? [];
|
||||||
},
|
},
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { LayoutType } from '@vben/types';
|
||||||
|
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
|
||||||
import NumberFieldItem from '../number-field-item.vue';
|
import NumberFieldItem from '../number-field-item.vue';
|
||||||
import SwitchItem from '../switch-item.vue';
|
import SwitchItem from '../switch-item.vue';
|
||||||
|
|
||||||
defineProps<{ disabled: boolean }>();
|
defineProps<{ currentLayout?: LayoutType; disabled: boolean }>();
|
||||||
|
|
||||||
const sidebarEnable = defineModel<boolean>('sidebarEnable');
|
const sidebarEnable = defineModel<boolean>('sidebarEnable');
|
||||||
const sidebarWidth = defineModel<number>('sidebarWidth');
|
const sidebarWidth = defineModel<number>('sidebarWidth');
|
||||||
const sidebarCollapsedShowTitle = defineModel<boolean>(
|
const sidebarCollapsedShowTitle = defineModel<boolean>(
|
||||||
'sidebarCollapsedShowTitle',
|
'sidebarCollapsedShowTitle',
|
||||||
);
|
);
|
||||||
|
const sidebarAutoActivateChild = defineModel<boolean>(
|
||||||
|
'sidebarAutoActivateChild',
|
||||||
|
);
|
||||||
const sidebarCollapsed = defineModel<boolean>('sidebarCollapsed');
|
const sidebarCollapsed = defineModel<boolean>('sidebarCollapsed');
|
||||||
|
const sidebarExpandOnHover = defineModel<boolean>('sidebarExpandOnHover');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -21,12 +27,28 @@ const sidebarCollapsed = defineModel<boolean>('sidebarCollapsed');
|
|||||||
<SwitchItem v-model="sidebarCollapsed" :disabled="!sidebarEnable || disabled">
|
<SwitchItem v-model="sidebarCollapsed" :disabled="!sidebarEnable || disabled">
|
||||||
{{ $t('preferences.sidebar.collapsed') }}
|
{{ $t('preferences.sidebar.collapsed') }}
|
||||||
</SwitchItem>
|
</SwitchItem>
|
||||||
|
<SwitchItem
|
||||||
|
v-model="sidebarExpandOnHover"
|
||||||
|
:disabled="!sidebarEnable || disabled || !sidebarCollapsed"
|
||||||
|
:tip="$t('preferences.sidebar.expandOnHoverTip')"
|
||||||
|
>
|
||||||
|
{{ $t('preferences.sidebar.expandOnHover') }}
|
||||||
|
</SwitchItem>
|
||||||
<SwitchItem
|
<SwitchItem
|
||||||
v-model="sidebarCollapsedShowTitle"
|
v-model="sidebarCollapsedShowTitle"
|
||||||
:disabled="!sidebarEnable || disabled || !sidebarCollapsed"
|
:disabled="!sidebarEnable || disabled || !sidebarCollapsed"
|
||||||
>
|
>
|
||||||
{{ $t('preferences.sidebar.collapsedShowTitle') }}
|
{{ $t('preferences.sidebar.collapsedShowTitle') }}
|
||||||
</SwitchItem>
|
</SwitchItem>
|
||||||
|
<SwitchItem
|
||||||
|
v-model="sidebarAutoActivateChild"
|
||||||
|
:disabled="
|
||||||
|
!sidebarEnable || currentLayout !== 'sidebar-mixed-nav' || disabled
|
||||||
|
"
|
||||||
|
:tip="$t('preferences.sidebar.autoActivateChildTip')"
|
||||||
|
>
|
||||||
|
{{ $t('preferences.sidebar.autoActivateChild') }}
|
||||||
|
</SwitchItem>
|
||||||
<NumberFieldItem
|
<NumberFieldItem
|
||||||
v-model="sidebarWidth"
|
v-model="sidebarWidth"
|
||||||
:disabled="!sidebarEnable || disabled"
|
:disabled="!sidebarEnable || disabled"
|
||||||
|
@ -87,6 +87,10 @@ const sidebarCollapsed = defineModel<boolean>('sidebarCollapsed');
|
|||||||
const sidebarCollapsedShowTitle = defineModel<boolean>(
|
const sidebarCollapsedShowTitle = defineModel<boolean>(
|
||||||
'sidebarCollapsedShowTitle',
|
'sidebarCollapsedShowTitle',
|
||||||
);
|
);
|
||||||
|
const sidebarAutoActivateChild = defineModel<boolean>(
|
||||||
|
'sidebarAutoActivateChild',
|
||||||
|
);
|
||||||
|
const SidebarExpandOnHover = defineModel<boolean>('sidebarExpandOnHover');
|
||||||
|
|
||||||
const headerEnable = defineModel<boolean>('headerEnable');
|
const headerEnable = defineModel<boolean>('headerEnable');
|
||||||
const headerMode = defineModel<LayoutHeaderModeType>('headerMode');
|
const headerMode = defineModel<LayoutHeaderModeType>('headerMode');
|
||||||
@ -299,10 +303,13 @@ async function handleReset() {
|
|||||||
|
|
||||||
<Block :title="$t('preferences.sidebar.title')">
|
<Block :title="$t('preferences.sidebar.title')">
|
||||||
<Sidebar
|
<Sidebar
|
||||||
|
v-model:sidebar-auto-activate-child="sidebarAutoActivateChild"
|
||||||
v-model:sidebar-collapsed="sidebarCollapsed"
|
v-model:sidebar-collapsed="sidebarCollapsed"
|
||||||
v-model:sidebar-collapsed-show-title="sidebarCollapsedShowTitle"
|
v-model:sidebar-collapsed-show-title="sidebarCollapsedShowTitle"
|
||||||
v-model:sidebar-enable="sidebarEnable"
|
v-model:sidebar-enable="sidebarEnable"
|
||||||
|
v-model:sidebar-expand-on-hover="SidebarExpandOnHover"
|
||||||
v-model:sidebar-width="sidebarWidth"
|
v-model:sidebar-width="sidebarWidth"
|
||||||
|
:current-layout="appLayout"
|
||||||
:disabled="!isSideMode"
|
:disabled="!isSideMode"
|
||||||
/>
|
/>
|
||||||
</Block>
|
</Block>
|
||||||
|
@ -45,7 +45,11 @@
|
|||||||
"width": "Width",
|
"width": "Width",
|
||||||
"visible": "Show Sidebar",
|
"visible": "Show Sidebar",
|
||||||
"collapsed": "Collpase Menu",
|
"collapsed": "Collpase Menu",
|
||||||
"collapsedShowTitle": "Show Menu Title"
|
"collapsedShowTitle": "Show Menu Title",
|
||||||
|
"autoActivateChild": "Auto Activate SubMenu",
|
||||||
|
"autoActivateChildTip": "`Enabled` to automatically activate the submenu while click menu.",
|
||||||
|
"expandOnHover": "Expand On Hover",
|
||||||
|
"expandOnHoverTip": "When the mouse hovers over menu, \n `Enabled` to expand children menus \n `Disabled` to expand whole sidebar."
|
||||||
},
|
},
|
||||||
"tabbar": {
|
"tabbar": {
|
||||||
"title": "Tabbar",
|
"title": "Tabbar",
|
||||||
|
@ -45,7 +45,11 @@
|
|||||||
"width": "宽度",
|
"width": "宽度",
|
||||||
"visible": "显示侧边栏",
|
"visible": "显示侧边栏",
|
||||||
"collapsed": "折叠菜单",
|
"collapsed": "折叠菜单",
|
||||||
"collapsedShowTitle": "折叠显示菜单名"
|
"collapsedShowTitle": "折叠显示菜单名",
|
||||||
|
"autoActivateChild": "自动激活子菜单",
|
||||||
|
"autoActivateChildTip": "点击顶层菜单时,自动激活第一个子菜单或者上一次激活的子菜单",
|
||||||
|
"expandOnHover": "鼠标悬停展开",
|
||||||
|
"expandOnHoverTip": "鼠标在折叠区域悬浮时,`启用`则展开当前子菜单,`禁用`则展开整个侧边栏"
|
||||||
},
|
},
|
||||||
"tabbar": {
|
"tabbar": {
|
||||||
"title": "标签栏",
|
"title": "标签栏",
|
||||||
|
Loading…
Reference in New Issue
Block a user