feat: 新增菜单自动折叠 (#744)

* fix: 点击tab导航栏,对应菜单层级没有自动展开

close #734

* feat: 当tab-route存在的项,menu都被展开

* feat: keep the currently expanded data

* feat: add setting `menuAutoCollapsed`
This commit is contained in:
阿菜 Cai 2024-08-19 02:02:52 +08:00 committed by GitHub
parent 8941a1329e
commit be3be09bee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 44 additions and 10 deletions

View File

@ -2,6 +2,7 @@ export default {
showFooter: true, showFooter: true,
isSidebarCompact: false, isSidebarCompact: false,
showBreadcrumb: false, showBreadcrumb: false,
menuAutoCollapsed: false,
mode: 'light', mode: 'light',
layout: 'side', layout: 'side',
splitMenu: false, splitMenu: false,

View File

@ -1,6 +1,14 @@
<template> <template>
<div :class="sideNavCls"> <div :class="sideNavCls">
<t-menu :class="menuCls" :theme="theme" :value="active" :collapsed="collapsed" :default-expanded="defaultExpanded"> <t-menu
:class="menuCls"
:theme="theme"
:value="active"
:collapsed="collapsed"
:expanded="expanded"
:expand-mutex="menuAutoCollapsed"
@expand="onExpanded"
>
<template #logo> <template #logo>
<span v-if="showLogo" :class="`${prefix}-side-nav-logo-wrapper`" @click="goHome"> <span v-if="showLogo" :class="`${prefix}-side-nav-logo-wrapper`" @click="goHome">
<component :is="getLogo()" :class="logoCls" /> <component :is="getLogo()" :class="logoCls" />
@ -16,15 +24,16 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import union from 'lodash/union'; import { difference, remove, union } from 'lodash';
import { MenuValue } from 'tdesign-vue-next';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { computed, onMounted } from 'vue'; import { computed, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import AssetLogoFull from '@/assets/assets-logo-full.svg?component'; import AssetLogoFull from '@/assets/assets-logo-full.svg?component';
import AssetLogo from '@/assets/assets-t-logo.svg?component'; import AssetLogo from '@/assets/assets-t-logo.svg?component';
import { prefix } from '@/config/global'; import { prefix } from '@/config/global';
import { getActive, getRoutesExpanded } from '@/router'; import { getActive } from '@/router';
import { useSettingStore } from '@/store'; import { useSettingStore } from '@/store';
import type { MenuRoute, ModeType } from '@/types/interface'; import type { MenuRoute, ModeType } from '@/types/interface';
@ -65,15 +74,27 @@ const props = defineProps({
}); });
const collapsed = computed(() => useSettingStore().isSidebarCompact); const collapsed = computed(() => useSettingStore().isSidebarCompact);
const menuAutoCollapsed = computed(() => useSettingStore().menuAutoCollapsed);
const active = computed(() => getActive()); const active = computed(() => getActive());
const defaultExpanded = computed(() => { const expanded = ref<MenuValue[]>([]);
const path = getActive();
const parentPath = path.substring(0, path.lastIndexOf('/')); watch(
const expanded = getRoutesExpanded(); () => active.value,
return union(expanded, parentPath === '' ? [] : [parentPath]); () => {
}); const path = getActive();
const parentPath = path.substring(0, path.lastIndexOf('/'));
expanded.value = menuAutoCollapsed.value ? [parentPath] : union([parentPath], expanded.value);
},
);
const onExpanded = (value: MenuValue[]) => {
const currentOperationMenu = difference(expanded.value, value);
const allExpanded = union(value, expanded.value);
remove(allExpanded, (item) => currentOperationMenu.includes(item));
expanded.value = allExpanded;
};
const sideMode = computed(() => { const sideMode = computed(() => {
const { theme } = props; const { theme } = props;
@ -127,6 +148,9 @@ const autoCollapsed = () => {
}; };
onMounted(() => { onMounted(() => {
const path = getActive();
const parentPath = path.substring(0, path.lastIndexOf('/'));
expanded.value = union([parentPath], expanded.value);
autoCollapsed(); autoCollapsed();
window.onresize = () => { window.onresize = () => {
autoCollapsed(); autoCollapsed();

View File

@ -95,6 +95,9 @@
<t-form-item :label="$t('layout.setting.element.useTagTabs')" name="isUseTabsRouter"> <t-form-item :label="$t('layout.setting.element.useTagTabs')" name="isUseTabsRouter">
<t-switch v-model="formData.isUseTabsRouter"></t-switch> <t-switch v-model="formData.isUseTabsRouter"></t-switch>
</t-form-item> </t-form-item>
<t-form-item :label="$t('layout.setting.element.menuAutoCollapsed')" name="menuAutoCollapsed">
<t-switch v-model="formData.menuAutoCollapsed"></t-switch>
</t-form-item>
</t-form> </t-form>
<div class="setting-info"> <div class="setting-info">
<p>{{ $t('layout.setting.tips') }}</p> <p>{{ $t('layout.setting.tips') }}</p>

View File

@ -42,6 +42,7 @@ export default {
showBreadcrumb: 'Show Breadcrumb', showBreadcrumb: 'Show Breadcrumb',
showFooter: 'Show Footer', showFooter: 'Show Footer',
useTagTabs: 'Use Tag Tabs', useTagTabs: 'Use Tag Tabs',
menuAutoCollapsed: 'Menu Auto Collapsed',
}, },
tips: 'Please copy and manually modify the configuration file: /src/config/style.ts', tips: 'Please copy and manually modify the configuration file: /src/config/style.ts',
copy: { copy: {

View File

@ -42,6 +42,7 @@ export default {
showBreadcrumb: '显示面包屑', showBreadcrumb: '显示面包屑',
showFooter: '显示页脚', showFooter: '显示页脚',
useTagTabs: '展示多标签Tab页', useTagTabs: '展示多标签Tab页',
menuAutoCollapsed: '菜单自动折叠',
}, },
tips: '请复制后手动修改配置文件: /src/config/style.ts', tips: '请复制后手动修改配置文件: /src/config/style.ts',
copy: { copy: {

View File

@ -39,6 +39,10 @@ export function mapModuleRouterList(modules: Record<string, unknown>): Array<Rou
return routerList; return routerList;
} }
/**
*
* @deprecated 使
*/
export const getRoutesExpanded = () => { export const getRoutesExpanded = () => {
const expandedRoutes: Array<string> = []; const expandedRoutes: Array<string> = [];