feat: The accordion mode of the menu is configurable
parent
a0423eb9ba
commit
c28adc9a94
|
@ -77,6 +77,8 @@ interface Preference {
|
||||||
logo: string;
|
logo: string;
|
||||||
/** logo是否可见 */
|
/** logo是否可见 */
|
||||||
logoVisible: boolean;
|
logoVisible: boolean;
|
||||||
|
/** 导航菜单手风琴模式 */
|
||||||
|
navigationAccordion: boolean;
|
||||||
/** 导航菜单是否切割,只在 layout=mixed-nav 生效 */
|
/** 导航菜单是否切割,只在 layout=mixed-nav 生效 */
|
||||||
navigationSplit: boolean;
|
navigationSplit: boolean;
|
||||||
/** 导航菜单风格 */
|
/** 导航菜单风格 */
|
||||||
|
|
|
@ -14,6 +14,7 @@ defineProps<{ disabled?: boolean; disabledNavigationSplit?: boolean }>();
|
||||||
|
|
||||||
const navigationStyle = defineModel<string>('navigationStyle');
|
const navigationStyle = defineModel<string>('navigationStyle');
|
||||||
const navigationSplit = defineModel<boolean>('navigationSplit');
|
const navigationSplit = defineModel<boolean>('navigationSplit');
|
||||||
|
const navigationAccordion = defineModel<boolean>('navigationAccordion');
|
||||||
|
|
||||||
const stylesItems: SelectListItem[] = [
|
const stylesItems: SelectListItem[] = [
|
||||||
{ label: $t('preference.rounded'), value: 'rounded' },
|
{ label: $t('preference.rounded'), value: 'rounded' },
|
||||||
|
@ -29,10 +30,16 @@ const stylesItems: SelectListItem[] = [
|
||||||
>
|
>
|
||||||
{{ $t('preference.navigation-style') }}
|
{{ $t('preference.navigation-style') }}
|
||||||
</ToggleItem>
|
</ToggleItem>
|
||||||
<SwitchItem v-model="navigationSplit" :disabled="disabledNavigationSplit">
|
<SwitchItem
|
||||||
|
v-model="navigationSplit"
|
||||||
|
:disabled="disabledNavigationSplit || disabled"
|
||||||
|
>
|
||||||
{{ $t('preference.navigation-split') }}
|
{{ $t('preference.navigation-split') }}
|
||||||
<template #tip>
|
<template #tip>
|
||||||
{{ $t('preference.navigation-split-tip') }}
|
{{ $t('preference.navigation-split-tip') }}
|
||||||
</template>
|
</template>
|
||||||
</SwitchItem>
|
</SwitchItem>
|
||||||
|
<SwitchItem v-model="navigationAccordion" :disabled="disabled">
|
||||||
|
{{ $t('preference.navigation-accordion') }}
|
||||||
|
</SwitchItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -52,11 +52,15 @@ function updateLocale(value: string) {
|
||||||
:page-progress="preference.pageProgress"
|
:page-progress="preference.pageProgress"
|
||||||
:tabs-icon="preference.tabsIcon"
|
:tabs-icon="preference.tabsIcon"
|
||||||
:locale="preference.locale"
|
:locale="preference.locale"
|
||||||
|
:navigation-accordion="preference.navigationAccordion"
|
||||||
:navigation-style="preference.navigationStyle"
|
:navigation-style="preference.navigationStyle"
|
||||||
:navigation-split="preference.navigationSplit"
|
:navigation-split="preference.navigationSplit"
|
||||||
:side-collapse-show-title="preference.sideCollapseShowTitle"
|
:side-collapse-show-title="preference.sideCollapseShowTitle"
|
||||||
:page-transition-enable="preference.pageTransitionEnable"
|
:page-transition-enable="preference.pageTransitionEnable"
|
||||||
@update:navigation-style="(value) => handleUpdate('navigationStyle', value)"
|
@update:navigation-style="(value) => handleUpdate('navigationStyle', value)"
|
||||||
|
@update:navigation-accordion="
|
||||||
|
(value) => handleUpdate('navigationAccordion', value)
|
||||||
|
"
|
||||||
@update:navigation-split="(value) => handleUpdate('navigationSplit', value)"
|
@update:navigation-split="(value) => handleUpdate('navigationSplit', value)"
|
||||||
@update:dynamic-title="(value) => handleUpdate('dynamicTitle', value)"
|
@update:dynamic-title="(value) => handleUpdate('dynamicTitle', value)"
|
||||||
@update:tabs-icon="(value) => handleUpdate('tabsIcon', value)"
|
@update:tabs-icon="(value) => handleUpdate('tabsIcon', value)"
|
||||||
|
|
|
@ -54,6 +54,7 @@ const colorGrayMode = defineModel<boolean>('colorGrayMode');
|
||||||
const colorPrimary = defineModel<string>('colorPrimary');
|
const colorPrimary = defineModel<string>('colorPrimary');
|
||||||
const navigationStyle = defineModel<string>('navigationStyle');
|
const navigationStyle = defineModel<string>('navigationStyle');
|
||||||
const navigationSplit = defineModel<boolean>('navigationSplit');
|
const navigationSplit = defineModel<boolean>('navigationSplit');
|
||||||
|
const navigationAccordion = defineModel<boolean>('navigationAccordion');
|
||||||
const pageProgress = defineModel<boolean>('pageProgress');
|
const pageProgress = defineModel<boolean>('pageProgress');
|
||||||
const pageTransition = defineModel<string>('pageTransition');
|
const pageTransition = defineModel<string>('pageTransition');
|
||||||
const pageTransitionEnable = defineModel<boolean>('pageTransitionEnable');
|
const pageTransitionEnable = defineModel<boolean>('pageTransitionEnable');
|
||||||
|
@ -197,6 +198,7 @@ function handleReset() {
|
||||||
<Navigation
|
<Navigation
|
||||||
v-model:navigation-style="navigationStyle"
|
v-model:navigation-style="navigationStyle"
|
||||||
v-model:navigation-split="navigationSplit"
|
v-model:navigation-split="navigationSplit"
|
||||||
|
v-model:navigation-accordion="navigationAccordion"
|
||||||
:disabled="isFullContent"
|
:disabled="isFullContent"
|
||||||
:disabled-navigation-split="!isMixedNav"
|
:disabled-navigation-split="!isMixedNav"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -50,6 +50,7 @@ function getTransitionName(route: RouteLocationNormalizedLoaded) {
|
||||||
<component
|
<component
|
||||||
:is="Component"
|
:is="Component"
|
||||||
v-if="renderRouteView"
|
v-if="renderRouteView"
|
||||||
|
v-show="!route.meta.iframeSrc"
|
||||||
:key="route.fullPath"
|
:key="route.fullPath"
|
||||||
class="h-[1000px]"
|
class="h-[1000px]"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -183,6 +183,7 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
|
||||||
<template #menu>
|
<template #menu>
|
||||||
<LayoutMenu
|
<LayoutMenu
|
||||||
mode="vertical"
|
mode="vertical"
|
||||||
|
:accordion="preference.navigationAccordion"
|
||||||
:rounded="isMenuRounded"
|
:rounded="isMenuRounded"
|
||||||
:collapse-show-title="preference.sideCollapseShowTitle"
|
:collapse-show-title="preference.sideCollapseShowTitle"
|
||||||
:collapse="preference.sideCollapse"
|
:collapse="preference.sideCollapse"
|
||||||
|
@ -206,6 +207,7 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
|
||||||
<!-- 侧边额外区域 -->
|
<!-- 侧边额外区域 -->
|
||||||
<template #side-extra>
|
<template #side-extra>
|
||||||
<LayoutExtraMenu
|
<LayoutExtraMenu
|
||||||
|
:accordion="preference.navigationAccordion"
|
||||||
:rounded="isMenuRounded"
|
:rounded="isMenuRounded"
|
||||||
:menus="wrapperMenus(extraMenus)"
|
:menus="wrapperMenus(extraMenus)"
|
||||||
:collapse="preference.sideExtraCollapse"
|
:collapse="preference.sideExtraCollapse"
|
||||||
|
|
|
@ -12,7 +12,10 @@ interface Props extends MenuProps {
|
||||||
menus: MenuRecordRaw[];
|
menus: MenuRecordRaw[];
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<Props>();
|
withDefaults(defineProps<Props>(), {
|
||||||
|
accordion: true,
|
||||||
|
menus: () => [],
|
||||||
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { navigation } = useNavigation();
|
const { navigation } = useNavigation();
|
||||||
|
@ -25,6 +28,7 @@ async function handleSelect(key: string) {
|
||||||
<template>
|
<template>
|
||||||
<Menu
|
<Menu
|
||||||
:rounded="rounded"
|
:rounded="rounded"
|
||||||
|
:accordion="accordion"
|
||||||
:collapse="collapse"
|
:collapse="collapse"
|
||||||
:default-active="route.path"
|
:default-active="route.path"
|
||||||
:menus="menus"
|
:menus="menus"
|
||||||
|
|
|
@ -8,6 +8,7 @@ interface Props extends MenuProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
accordion: true,
|
||||||
menus: () => [],
|
menus: () => [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ function handleMenuSelect(key: string) {
|
||||||
:rounded="rounded"
|
:rounded="rounded"
|
||||||
:collapse-show-title="collapseShowTitle"
|
:collapse-show-title="collapseShowTitle"
|
||||||
:collapse="collapse"
|
:collapse="collapse"
|
||||||
|
:accordion="accordion"
|
||||||
:default-active="defaultActive"
|
:default-active="defaultActive"
|
||||||
:menus="menus"
|
:menus="menus"
|
||||||
:theme="theme"
|
:theme="theme"
|
||||||
|
|
|
@ -78,6 +78,7 @@ preference:
|
||||||
navigation-menu: Navigation Menu
|
navigation-menu: Navigation Menu
|
||||||
navigation-style: Navigation menu style
|
navigation-style: Navigation menu style
|
||||||
navigation-split: Navigation Menu Separation
|
navigation-split: Navigation Menu Separation
|
||||||
|
navigation-accordion: Sidebar Navigation Menu Accordion mode
|
||||||
navigation-split-tip: When enabled, the sidebar shows the top bar's submenu
|
navigation-split-tip: When enabled, the sidebar shows the top bar's submenu
|
||||||
interface-control: Interface Layout Control
|
interface-control: Interface Layout Control
|
||||||
breadcrumb: Breadcrumb
|
breadcrumb: Breadcrumb
|
||||||
|
|
|
@ -73,6 +73,7 @@ preference:
|
||||||
animation: 动画
|
animation: 动画
|
||||||
navigation-menu: 导航菜单
|
navigation-menu: 导航菜单
|
||||||
navigation-style: 导航菜单风格
|
navigation-style: 导航菜单风格
|
||||||
|
navigation-accordion: 侧边导航菜单手风琴模式
|
||||||
navigation-split: 导航菜单分离
|
navigation-split: 导航菜单分离
|
||||||
navigation-split-tip: 开启时,侧边栏显示顶栏对应菜单的子菜单
|
navigation-split-tip: 开启时,侧边栏显示顶栏对应菜单的子菜单
|
||||||
interface-control: 界面布局控制
|
interface-control: 界面布局控制
|
||||||
|
|
|
@ -27,6 +27,7 @@ const defaultPreference: Preference = {
|
||||||
locale: 'zh-CN',
|
locale: 'zh-CN',
|
||||||
logo: 'https://cdn.jsdelivr.net/gh/vbenjs/vben-cdn-static@0.1.2/vben-admin/admin-logo.png',
|
logo: 'https://cdn.jsdelivr.net/gh/vbenjs/vben-cdn-static@0.1.2/vben-admin/admin-logo.png',
|
||||||
logoVisible: true,
|
logoVisible: true,
|
||||||
|
navigationAccordion: true,
|
||||||
navigationSplit: true,
|
navigationSplit: true,
|
||||||
navigationStyle: 'rounded',
|
navigationStyle: 'rounded',
|
||||||
pageProgress: true,
|
pageProgress: true,
|
||||||
|
|
|
@ -269,7 +269,7 @@ const useTabsStore = defineStore('tabs', {
|
||||||
await this.closeTab(this.tabs[index], router);
|
await this.closeTab(this.tabs[index], router);
|
||||||
},
|
},
|
||||||
getTabPath(tab: RouteRecordNormalized | TabItem) {
|
getTabPath(tab: RouteRecordNormalized | TabItem) {
|
||||||
return (tab as TabItem).fullPath || tab.path;
|
return decodeURIComponent((tab as TabItem).fullPath || tab.path);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @zh_CN 固定标签页
|
* @zh_CN 固定标签页
|
||||||
|
|
Loading…
Reference in New Issue