mirror of
https://github.com/Tencent/tdesign-vue-next-starter.git
synced 2024-12-22 18:20:59 +08:00
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:
parent
8941a1329e
commit
be3be09bee
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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> = [];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user