feat: header mixed layout (#5263)
* feat: new layout header-mixed * fix: header-mixed layout update * feat: layout preference update * fix: extra menus follow layout setting
This commit is contained in:
parent
07c4ad05f4
commit
ff8d5ca351
1
packages/@core/base/typings/src/app.d.ts
vendored
1
packages/@core/base/typings/src/app.d.ts
vendored
@ -1,5 +1,6 @@
|
||||
type LayoutType =
|
||||
| 'full-content'
|
||||
| 'header-mixed-nav'
|
||||
| 'header-nav'
|
||||
| 'mixed-nav'
|
||||
| 'sidebar-mixed-nav'
|
||||
|
@ -82,6 +82,10 @@ function usePreferences() {
|
||||
() => appPreferences.value.layout === 'header-nav',
|
||||
);
|
||||
|
||||
const isHeaderMixedNav = computed(
|
||||
() => appPreferences.value.layout === 'header-mixed-nav',
|
||||
);
|
||||
|
||||
/**
|
||||
* @zh_CN 是否为混合导航模式
|
||||
*/
|
||||
@ -93,7 +97,12 @@ function usePreferences() {
|
||||
* @zh_CN 是否包含侧边导航模式
|
||||
*/
|
||||
const isSideMode = computed(() => {
|
||||
return isMixedNav.value || isSideMixedNav.value || isSideNav.value;
|
||||
return (
|
||||
isMixedNav.value ||
|
||||
isSideMixedNav.value ||
|
||||
isSideNav.value ||
|
||||
isHeaderMixedNav.value
|
||||
);
|
||||
});
|
||||
|
||||
const sidebarCollapsed = computed(() => {
|
||||
@ -214,6 +223,7 @@ function usePreferences() {
|
||||
globalSearchShortcutKey,
|
||||
isDark,
|
||||
isFullContent,
|
||||
isHeaderMixedNav,
|
||||
isHeaderNav,
|
||||
isMixedNav,
|
||||
isMobile,
|
||||
|
@ -31,9 +31,17 @@ export function useLayout(props: VbenLayoutProps) {
|
||||
*/
|
||||
const isMixedNav = computed(() => currentLayout.value === 'mixed-nav');
|
||||
|
||||
/**
|
||||
* 是否为头部混合模式
|
||||
*/
|
||||
const isHeaderMixedNav = computed(
|
||||
() => currentLayout.value === 'header-mixed-nav',
|
||||
);
|
||||
|
||||
return {
|
||||
currentLayout,
|
||||
isFullContent,
|
||||
isHeaderMixedNav,
|
||||
isHeaderNav,
|
||||
isMixedNav,
|
||||
isSidebarMixedNav,
|
||||
|
@ -87,6 +87,7 @@ const { y: mouseY } = useMouse({ target: contentRef, type: 'client' });
|
||||
const {
|
||||
currentLayout,
|
||||
isFullContent,
|
||||
isHeaderMixedNav,
|
||||
isHeaderNav,
|
||||
isMixedNav,
|
||||
isSidebarMixedNav,
|
||||
@ -112,7 +113,9 @@ const getSideCollapseWidth = computed(() => {
|
||||
const { sidebarCollapseShowTitle, sidebarMixedWidth, sideCollapseWidth } =
|
||||
props;
|
||||
|
||||
return sidebarCollapseShowTitle || isSidebarMixedNav.value
|
||||
return sidebarCollapseShowTitle ||
|
||||
isSidebarMixedNav.value ||
|
||||
isHeaderMixedNav.value
|
||||
? sidebarMixedWidth
|
||||
: sideCollapseWidth;
|
||||
});
|
||||
@ -145,12 +148,15 @@ const getSidebarWidth = computed(() => {
|
||||
|
||||
if (
|
||||
!sidebarEnableState.value ||
|
||||
(sidebarHidden && !isSidebarMixedNav.value && !isMixedNav.value)
|
||||
(sidebarHidden &&
|
||||
!isSidebarMixedNav.value &&
|
||||
!isMixedNav.value &&
|
||||
!isHeaderMixedNav.value)
|
||||
) {
|
||||
return width;
|
||||
}
|
||||
|
||||
if (isSidebarMixedNav.value && !isMobile) {
|
||||
if ((isHeaderMixedNav.value || isSidebarMixedNav.value) && !isMobile) {
|
||||
width = sidebarMixedWidth;
|
||||
} else if (sidebarCollapse.value) {
|
||||
width = isMobile ? 0 : getSideCollapseWidth.value;
|
||||
@ -176,7 +182,8 @@ const isSideMode = computed(
|
||||
() =>
|
||||
currentLayout.value === 'mixed-nav' ||
|
||||
currentLayout.value === 'sidebar-mixed-nav' ||
|
||||
currentLayout.value === 'sidebar-nav',
|
||||
currentLayout.value === 'sidebar-nav' ||
|
||||
currentLayout.value === 'header-mixed-nav',
|
||||
);
|
||||
|
||||
/**
|
||||
@ -213,7 +220,7 @@ const mainStyle = computed(() => {
|
||||
) {
|
||||
// fixed模式下生效
|
||||
const isSideNavEffective =
|
||||
isSidebarMixedNav.value &&
|
||||
(isSidebarMixedNav.value || isHeaderMixedNav.value) &&
|
||||
sidebarExpandOnHover.value &&
|
||||
sidebarExtraVisible.value;
|
||||
|
||||
@ -476,7 +483,7 @@ const idMainContent = ELEMENT_ID_MAIN_CONTENT;
|
||||
:extra-width="sidebarExtraWidth"
|
||||
:fixed-extra="sidebarExpandOnHover"
|
||||
:header-height="isMixedNav ? 0 : headerHeight"
|
||||
:is-sidebar-mixed="isSidebarMixedNav"
|
||||
:is-sidebar-mixed="isSidebarMixedNav || isHeaderMixedNav"
|
||||
:margin-top="sidebarMarginTop"
|
||||
:mixed-width="sidebarMixedWidth"
|
||||
:show="showSidebar"
|
||||
@ -489,7 +496,7 @@ const idMainContent = ELEMENT_ID_MAIN_CONTENT;
|
||||
<slot name="logo"></slot>
|
||||
</template>
|
||||
|
||||
<template v-if="isSidebarMixedNav">
|
||||
<template v-if="isSidebarMixedNav || isHeaderMixedNav">
|
||||
<slot name="mixed-menu"></slot>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { MenuRecordRaw } from '@vben/types';
|
||||
|
||||
import { computed, useSlots, watch } from 'vue';
|
||||
import { computed, type SetupContext, useSlots, watch } from 'vue';
|
||||
|
||||
import { useRefresh } from '@vben/hooks';
|
||||
import { $t } from '@vben/locales';
|
||||
@ -39,6 +39,7 @@ const {
|
||||
isMixedNav,
|
||||
isMobile,
|
||||
isSideMixedNav,
|
||||
isHeaderMixedNav,
|
||||
layout,
|
||||
preferencesButtonPosition,
|
||||
sidebarCollapsed,
|
||||
@ -83,11 +84,16 @@ const logoCollapsed = computed(() => {
|
||||
if (isHeaderNav.value || isMixedNav.value) {
|
||||
return false;
|
||||
}
|
||||
return sidebarCollapsed.value || isSideMixedNav.value;
|
||||
return (
|
||||
sidebarCollapsed.value || isSideMixedNav.value || isHeaderMixedNav.value
|
||||
);
|
||||
});
|
||||
|
||||
const showHeaderNav = computed(() => {
|
||||
return !isMobile.value && (isHeaderNav.value || isMixedNav.value);
|
||||
return (
|
||||
!isMobile.value &&
|
||||
(isHeaderNav.value || isMixedNav.value || isHeaderMixedNav.value)
|
||||
);
|
||||
});
|
||||
|
||||
// 侧边多列菜单
|
||||
@ -108,6 +114,8 @@ const {
|
||||
headerMenus,
|
||||
sidebarActive,
|
||||
sidebarMenus,
|
||||
mixedSidebarActive,
|
||||
mixHeaderMenus,
|
||||
sidebarVisible,
|
||||
} = useMixedMenu();
|
||||
|
||||
@ -154,7 +162,7 @@ watch(
|
||||
// 语言更新后,刷新页面
|
||||
watch(() => preferences.app.locale, refresh, { flush: 'post' });
|
||||
|
||||
const slots = useSlots();
|
||||
const slots: SetupContext['slots'] = useSlots();
|
||||
const headerSlots = computed(() => {
|
||||
return Object.keys(slots).filter((key) => key.startsWith('header-'));
|
||||
});
|
||||
@ -267,8 +275,8 @@ const headerSlots = computed(() => {
|
||||
</template>
|
||||
<template #mixed-menu>
|
||||
<LayoutMixedMenu
|
||||
:active-path="extraActiveMenu"
|
||||
:menus="wrapperMenus(headerMenus, false)"
|
||||
:active-path="isHeaderMixedNav ? mixedSidebarActive : extraActiveMenu"
|
||||
:menus="wrapperMenus(mixHeaderMenus, false)"
|
||||
:rounded="isMenuRounded"
|
||||
:theme="sidebarTheme"
|
||||
@default-select="handleDefaultSelect"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { MenuRecordRaw } from '@vben/types';
|
||||
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { preferences } from '@vben/preferences';
|
||||
@ -17,7 +17,7 @@ function useExtraMenu() {
|
||||
|
||||
/** 记录当前顶级菜单下哪个子菜单最后激活 */
|
||||
const defaultSubMap = new Map<string, string>();
|
||||
|
||||
const extraRootMenus = ref<MenuRecordRaw[]>([]);
|
||||
const route = useRoute();
|
||||
const extraMenus = ref<MenuRecordRaw[]>([]);
|
||||
const sidebarExtraVisible = ref<boolean>(false);
|
||||
@ -49,11 +49,13 @@ function useExtraMenu() {
|
||||
* @param menu
|
||||
* @param rootMenu
|
||||
*/
|
||||
const handleDefaultSelect = (
|
||||
const handleDefaultSelect = async (
|
||||
menu: MenuRecordRaw,
|
||||
rootMenu?: MenuRecordRaw,
|
||||
) => {
|
||||
extraMenus.value = rootMenu?.children ?? [];
|
||||
await nextTick();
|
||||
|
||||
extraMenus.value = rootMenu?.children ?? extraRootMenus.value ?? [];
|
||||
extraActiveMenu.value = menu.parents?.[0] ?? menu.path;
|
||||
|
||||
if (preferences.sidebar.expandOnHover) {
|
||||
@ -65,17 +67,16 @@ function useExtraMenu() {
|
||||
* 侧边菜单鼠标移出事件
|
||||
*/
|
||||
const handleSideMouseLeave = () => {
|
||||
// const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath(
|
||||
// menus.value,
|
||||
// route.path,
|
||||
// );
|
||||
calcExtraMenus(route.path);
|
||||
if (preferences.sidebar.expandOnHover) {
|
||||
sidebarExtraVisible.value = extraMenus.value.length > 0;
|
||||
return;
|
||||
}
|
||||
sidebarExtraVisible.value = false;
|
||||
|
||||
const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath(
|
||||
menus.value,
|
||||
route.path,
|
||||
);
|
||||
extraActiveMenu.value = rootMenuPath ?? findMenu?.path ?? '';
|
||||
extraMenus.value = rootMenu?.children ?? [];
|
||||
};
|
||||
|
||||
const handleMenuMouseEnter = (menu: MenuRecordRaw) => {
|
||||
@ -87,20 +88,36 @@ function useExtraMenu() {
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
(path) => {
|
||||
const currentPath = route.meta?.activePath || path;
|
||||
// if (preferences.sidebar.expandOnHover) {
|
||||
// return;
|
||||
// }
|
||||
const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath(
|
||||
menus.value,
|
||||
function calcExtraMenus(path: string) {
|
||||
const currentPath = route.meta?.activePath || path;
|
||||
const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath(
|
||||
menus.value,
|
||||
currentPath,
|
||||
);
|
||||
if (preferences.app.layout === 'header-mixed-nav') {
|
||||
const subExtra = findRootMenuByPath(
|
||||
rootMenu?.children ?? [],
|
||||
currentPath,
|
||||
1,
|
||||
);
|
||||
extraRootMenus.value = subExtra.rootMenu?.children ?? [];
|
||||
extraActiveMenu.value = subExtra.rootMenuPath ?? '';
|
||||
extraMenus.value = subExtra.rootMenu?.children ?? [];
|
||||
} else {
|
||||
extraRootMenus.value = rootMenu?.children ?? [];
|
||||
if (rootMenuPath) defaultSubMap.set(rootMenuPath, currentPath);
|
||||
extraActiveMenu.value = rootMenuPath ?? findMenu?.path ?? '';
|
||||
extraMenus.value = rootMenu?.children ?? [];
|
||||
}
|
||||
if (preferences.sidebar.expandOnHover) {
|
||||
sidebarExtraVisible.value = extraMenus.value.length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [route.path, preferences.app.layout],
|
||||
([path]) => {
|
||||
calcExtraMenus(path || '');
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
@ -15,12 +15,16 @@ function useMixedMenu() {
|
||||
const route = useRoute();
|
||||
const splitSideMenus = ref<MenuRecordRaw[]>([]);
|
||||
const rootMenuPath = ref<string>('');
|
||||
const mixedRootMenuPath = ref<string>('');
|
||||
const mixExtraMenus = ref<MenuRecordRaw[]>([]);
|
||||
/** 记录当前顶级菜单下哪个子菜单最后激活 */
|
||||
const defaultSubMap = new Map<string, string>();
|
||||
const { isMixedNav } = usePreferences();
|
||||
const { isMixedNav, isHeaderMixedNav } = usePreferences();
|
||||
|
||||
const needSplit = computed(
|
||||
() => preferences.navigation.split && isMixedNav.value,
|
||||
() =>
|
||||
(preferences.navigation.split && isMixedNav.value) ||
|
||||
isHeaderMixedNav.value,
|
||||
);
|
||||
|
||||
const sidebarVisible = computed(() => {
|
||||
@ -54,6 +58,10 @@ function useMixedMenu() {
|
||||
return needSplit.value ? splitSideMenus.value : menus.value;
|
||||
});
|
||||
|
||||
const mixHeaderMenus = computed(() => {
|
||||
return isHeaderMixedNav.value ? sidebarMenus.value : headerMenus.value;
|
||||
});
|
||||
|
||||
/**
|
||||
* 侧边菜单激活路径
|
||||
*/
|
||||
@ -61,6 +69,10 @@ function useMixedMenu() {
|
||||
return (route?.meta?.activePath as string) ?? route.path;
|
||||
});
|
||||
|
||||
const mixedSidebarActive = computed(() => {
|
||||
return mixedRootMenuPath.value || sidebarActive.value;
|
||||
});
|
||||
|
||||
/**
|
||||
* 头部菜单激活路径
|
||||
*/
|
||||
@ -118,6 +130,9 @@ function useMixedMenu() {
|
||||
if (!rootMenu) {
|
||||
rootMenu = menus.value.find((item) => item.path === path);
|
||||
}
|
||||
const result = findRootMenuByPath(rootMenu?.children || [], path, 1);
|
||||
mixedRootMenuPath.value = result.rootMenuPath ?? '';
|
||||
mixExtraMenus.value = result.rootMenu?.children ?? [];
|
||||
rootMenuPath.value = rootMenu?.path ?? '';
|
||||
splitSideMenus.value = rootMenu?.children ?? [];
|
||||
}
|
||||
@ -145,6 +160,9 @@ function useMixedMenu() {
|
||||
headerMenus,
|
||||
sidebarActive,
|
||||
sidebarMenus,
|
||||
mixedSidebarActive,
|
||||
mixHeaderMenus,
|
||||
mixExtraMenus,
|
||||
sidebarVisible,
|
||||
};
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import { VbenTooltip } from '@vben-core/shadcn-ui';
|
||||
|
||||
import {
|
||||
FullContent,
|
||||
HeaderMixedNav,
|
||||
HeaderNav,
|
||||
MixedNav,
|
||||
SidebarMixedNav,
|
||||
@ -33,6 +34,7 @@ const components: Record<LayoutType, Component> = {
|
||||
'mixed-nav': MixedNav,
|
||||
'sidebar-mixed-nav': SidebarMixedNav,
|
||||
'sidebar-nav': SidebarNav,
|
||||
'header-mixed-nav': HeaderMixedNav,
|
||||
};
|
||||
|
||||
const PRESET = computed((): PresetItem[] => [
|
||||
@ -56,6 +58,11 @@ const PRESET = computed((): PresetItem[] => [
|
||||
tip: $t('preferences.mixedMenuTip'),
|
||||
type: 'mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.headerTwoColumn'),
|
||||
tip: $t('preferences.headerTwoColumnTip'),
|
||||
type: 'header-mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.fullContent'),
|
||||
tip: $t('preferences.fullContentTip'),
|
||||
|
@ -44,7 +44,7 @@ const sidebarExpandOnHover = defineModel<boolean>('sidebarExpandOnHover');
|
||||
v-model="sidebarAutoActivateChild"
|
||||
:disabled="
|
||||
!sidebarEnable ||
|
||||
!['sidebar-mixed-nav', 'mixed-nav', 'sidebar-nav'].includes(
|
||||
!['sidebar-mixed-nav', 'mixed-nav', 'header-mixed-nav'].includes(
|
||||
currentLayout as string,
|
||||
) ||
|
||||
disabled
|
||||
|
@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<svg
|
||||
class="custom-radio-image"
|
||||
fill="none"
|
||||
height="66"
|
||||
width="104"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g>
|
||||
<rect
|
||||
id="svg_1"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.02"
|
||||
height="66"
|
||||
rx="4"
|
||||
stroke="null"
|
||||
width="104"
|
||||
x="0.13514"
|
||||
y="0.13514"
|
||||
/>
|
||||
<path
|
||||
id="svg_2"
|
||||
d="m-3.37838,3.7543a1.93401,4.02457 0 0 1 1.93401,-4.02457l11.3488,0l0,66.40541l-11.3488,0a1.93401,4.02457 0 0 1 -1.93401,-4.02457l0,-58.35627z"
|
||||
fill="hsl(var(--primary))"
|
||||
stroke="null"
|
||||
/>
|
||||
<rect
|
||||
id="svg_3"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="5.47439"
|
||||
x="1.64059"
|
||||
y="15.46086"
|
||||
/>
|
||||
<rect
|
||||
id="svg_4"
|
||||
fill="#ffffff"
|
||||
height="7.67897"
|
||||
rx="2"
|
||||
stroke="null"
|
||||
width="8.18938"
|
||||
x="0.58676"
|
||||
y="1.42154"
|
||||
/>
|
||||
<rect
|
||||
id="svg_8"
|
||||
fill="hsl(var(--primary))"
|
||||
height="9.07027"
|
||||
rx="2"
|
||||
stroke="null"
|
||||
width="75.91967"
|
||||
x="25.38277"
|
||||
y="1.42876"
|
||||
/>
|
||||
<rect
|
||||
id="svg_9"
|
||||
fill="#b2b2b2"
|
||||
height="4.4"
|
||||
rx="1"
|
||||
stroke="null"
|
||||
width="3.925"
|
||||
x="27.91529"
|
||||
y="3.69284"
|
||||
/>
|
||||
<rect
|
||||
id="svg_10"
|
||||
fill="#b2b2b2"
|
||||
height="4.4"
|
||||
rx="1"
|
||||
stroke="null"
|
||||
width="3.925"
|
||||
x="80.75054"
|
||||
y="3.62876"
|
||||
/>
|
||||
<rect
|
||||
id="svg_11"
|
||||
fill="#b2b2b2"
|
||||
height="4.4"
|
||||
rx="1"
|
||||
stroke="null"
|
||||
width="3.925"
|
||||
x="87.78868"
|
||||
y="3.69981"
|
||||
/>
|
||||
<rect
|
||||
id="svg_12"
|
||||
fill="#b2b2b2"
|
||||
height="4.4"
|
||||
rx="1"
|
||||
stroke="null"
|
||||
width="3.925"
|
||||
x="94.6847"
|
||||
y="3.62876"
|
||||
/>
|
||||
<rect
|
||||
id="svg_13"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.08"
|
||||
height="21.51892"
|
||||
rx="2"
|
||||
stroke="null"
|
||||
width="42.9287"
|
||||
x="58.75427"
|
||||
y="14.613"
|
||||
/>
|
||||
<rect
|
||||
id="svg_14"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.08"
|
||||
height="20.97838"
|
||||
rx="2"
|
||||
stroke="null"
|
||||
width="28.36894"
|
||||
x="26.14342"
|
||||
y="14.613"
|
||||
/>
|
||||
<rect
|
||||
id="svg_15"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.08"
|
||||
height="21.65405"
|
||||
rx="2"
|
||||
stroke="null"
|
||||
width="75.09493"
|
||||
x="26.34264"
|
||||
y="39.68822"
|
||||
/>
|
||||
<rect
|
||||
id="svg_5"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="5.47439"
|
||||
x="1.79832"
|
||||
y="28.39462"
|
||||
/>
|
||||
<rect
|
||||
id="svg_6"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="5.47439"
|
||||
x="1.64059"
|
||||
y="41.80156"
|
||||
/>
|
||||
<rect
|
||||
id="svg_7"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="5.47439"
|
||||
x="1.64059"
|
||||
y="55.36623"
|
||||
/>
|
||||
<rect
|
||||
id="svg_16"
|
||||
fill="currentColor"
|
||||
fill-opacity="0.08"
|
||||
height="65.72065"
|
||||
stroke="null"
|
||||
width="12.49265"
|
||||
x="9.85477"
|
||||
y="-0.02618"
|
||||
/>
|
||||
<rect
|
||||
id="svg_21"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="7.52486"
|
||||
x="35.14924"
|
||||
y="4.07319"
|
||||
/>
|
||||
<rect
|
||||
id="svg_22"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="7.52486"
|
||||
x="47.25735"
|
||||
y="4.20832"
|
||||
/>
|
||||
<rect
|
||||
id="svg_23"
|
||||
fill="#e5e5e5"
|
||||
height="2.789"
|
||||
rx="1.395"
|
||||
stroke="null"
|
||||
width="7.52486"
|
||||
x="59.23033"
|
||||
y="4.07319"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
@ -2,6 +2,7 @@ import HeaderNav from './header-nav.vue';
|
||||
|
||||
export { default as ContentCompact } from './content-compact.vue';
|
||||
export { default as FullContent } from './full-content.vue';
|
||||
export { default as HeaderMixedNav } from './header-mixed-nav.vue';
|
||||
export { default as MixedNav } from './mixed-nav.vue';
|
||||
export { default as SidebarMixedNav } from './sidebar-mixed-nav.vue';
|
||||
export { default as SidebarNav } from './sidebar-nav.vue';
|
||||
|
@ -17,7 +17,9 @@
|
||||
"horizontalTip": "水平菜单模式,菜单全部显示在顶部",
|
||||
"twoColumn": "双列菜单",
|
||||
"twoColumnTip": "垂直双列菜单模式",
|
||||
"mixedMenu": "混合菜单",
|
||||
"headerTwoColumn": "混合双列",
|
||||
"headerTwoColumnTip": "双列、水平菜单共存模式",
|
||||
"mixedMenu": "混合垂直",
|
||||
"mixedMenuTip": "垂直水平菜单共存",
|
||||
"fullContent": "内容全屏",
|
||||
"fullContentTip": "不显示任何菜单,只显示内容主体",
|
||||
|
@ -21,9 +21,9 @@ function findMenuByPath(
|
||||
* @param menus
|
||||
* @param path
|
||||
*/
|
||||
function findRootMenuByPath(menus: MenuRecordRaw[], path?: string) {
|
||||
function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level = 0) {
|
||||
const findMenu = findMenuByPath(menus, path);
|
||||
const rootMenuPath = findMenu?.parents?.[0];
|
||||
const rootMenuPath = findMenu?.parents?.[level];
|
||||
const rootMenu = rootMenuPath
|
||||
? menus.find((item) => item.path === rootMenuPath)
|
||||
: undefined;
|
||||
|
Loading…
Reference in New Issue
Block a user