feat(layout): add sidebar-topbar layout
This commit is contained in:
parent
0ed2928c19
commit
d921b78951
|
@ -3,7 +3,8 @@ type LayoutType =
|
|||
| 'header-nav'
|
||||
| 'mixed-nav'
|
||||
| 'sidebar-mixed-nav'
|
||||
| 'sidebar-nav';
|
||||
| 'sidebar-nav'
|
||||
| 'sidebar-topbar';
|
||||
|
||||
type ThemeModeType = 'auto' | 'dark' | 'light';
|
||||
|
||||
|
|
|
@ -104,6 +104,8 @@ interface HeaderPreferences {
|
|||
hidden: boolean;
|
||||
/** header显示模式 */
|
||||
mode: LayoutHeaderModeType;
|
||||
/** header高度,适用于 layout 为 sidebar-topbar 模式 */
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface LogoPreferences {
|
||||
|
|
|
@ -97,6 +97,7 @@ interface VbenLayoutProps {
|
|||
* header-nav 顶部菜单布局
|
||||
* mixed-nav 侧边&顶部菜单布局
|
||||
* sidebar-mixed-nav 侧边混合菜单布局
|
||||
* sidebar-topbar 侧边菜单+顶部栏布局
|
||||
* full-content 全屏内容布局
|
||||
* @default sidebar-nav
|
||||
*/
|
||||
|
|
|
@ -120,7 +120,11 @@ const sidebarEnableState = computed(() => {
|
|||
*/
|
||||
const sidebarMarginTop = computed(() => {
|
||||
const { headerHeight, isMobile } = props;
|
||||
return isMixedNav.value && !isMobile ? headerHeight : 0;
|
||||
console.log(props);
|
||||
return (isMixedNav.value && !isMobile) ||
|
||||
currentLayout.value === 'sidebar-topbar'
|
||||
? headerHeight
|
||||
: 0;
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -167,7 +171,8 @@ const isSideMode = computed(
|
|||
() =>
|
||||
currentLayout.value === 'mixed-nav' ||
|
||||
currentLayout.value === 'sidebar-mixed-nav' ||
|
||||
currentLayout.value === 'sidebar-nav',
|
||||
currentLayout.value === 'sidebar-nav' ||
|
||||
currentLayout.value === 'sidebar-topbar',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -199,6 +204,7 @@ const mainStyle = computed(() => {
|
|||
headerFixed.value &&
|
||||
currentLayout.value !== 'header-nav' &&
|
||||
currentLayout.value !== 'mixed-nav' &&
|
||||
currentLayout.value !== 'sidebar-topbar' &&
|
||||
showSidebar.value &&
|
||||
!props.isMobile
|
||||
) {
|
||||
|
@ -291,7 +297,10 @@ const headerWrapperStyle = computed((): CSSProperties => {
|
|||
const fixed = headerFixed.value;
|
||||
return {
|
||||
height: isFullContent.value ? '0' : `${headerWrapperHeight.value}px`,
|
||||
left: isMixedNav.value ? 0 : mainStyle.value.sidebarAndExtraWidth,
|
||||
left:
|
||||
isMixedNav.value || currentLayout.value === 'sidebar-topbar'
|
||||
? 0
|
||||
: mainStyle.value.sidebarAndExtraWidth,
|
||||
position: fixed ? 'fixed' : 'static',
|
||||
top:
|
||||
headerIsHidden.value || isFullContent.value
|
||||
|
@ -335,12 +344,18 @@ const showHeaderToggleButton = computed(() => {
|
|||
isSideMode.value &&
|
||||
!isSidebarMixedNav.value &&
|
||||
!isMixedNav.value &&
|
||||
!props.isMobile)
|
||||
!props.isMobile &&
|
||||
currentLayout.value !== 'sidebar-topbar')
|
||||
);
|
||||
});
|
||||
|
||||
const showHeaderLogo = computed(() => {
|
||||
return !isSideMode.value || isMixedNav.value || props.isMobile;
|
||||
return (
|
||||
!isSideMode.value ||
|
||||
isMixedNav.value ||
|
||||
props.isMobile ||
|
||||
currentLayout.value === 'sidebar-topbar'
|
||||
);
|
||||
});
|
||||
|
||||
watch(
|
||||
|
@ -454,7 +469,10 @@ function handleHeaderToggle() {
|
|||
:z-index="sidebarZIndex"
|
||||
@leave="() => emit('sideMouseLeave')"
|
||||
>
|
||||
<template v-if="isSideMode && !isMixedNav" #logo>
|
||||
<template
|
||||
v-if="isSideMode && !isMixedNav && currentLayout !== 'sidebar-topbar'"
|
||||
#logo
|
||||
>
|
||||
<slot name="logo"></slot>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ const headerSlots = computed(() => {
|
|||
<VbenAdminLayout
|
||||
v-model:sidebar-extra-visible="sidebarExtraVisible"
|
||||
:content-compact="preferences.app.contentCompact"
|
||||
:header-height="preferences.header.height"
|
||||
:footer-enable="preferences.footer.enable"
|
||||
:footer-fixed="preferences.footer.fixed"
|
||||
:header-hidden="preferences.header.hidden"
|
||||
|
@ -211,6 +212,7 @@ const headerSlots = computed(() => {
|
|||
#breadcrumb
|
||||
>
|
||||
<Breadcrumb
|
||||
v-if="preferences.app.layout !== 'sidebar-topbar'"
|
||||
:hide-when-only-one="preferences.breadcrumb.hideOnlyOne"
|
||||
:show-home="preferences.breadcrumb.showHome"
|
||||
:show-icon="preferences.breadcrumb.showIcon"
|
||||
|
|
|
@ -33,6 +33,7 @@ const components: Record<LayoutType, Component> = {
|
|||
'mixed-nav': MixedNav,
|
||||
'sidebar-mixed-nav': SidebarMixedNav,
|
||||
'sidebar-nav': SidebarNav,
|
||||
'sidebar-topbar': MixedNav,
|
||||
};
|
||||
|
||||
const PRESET = computed((): PresetItem[] => [
|
||||
|
@ -61,6 +62,11 @@ const PRESET = computed((): PresetItem[] => [
|
|||
tip: $t('preferences.fullContentTip'),
|
||||
type: 'full-content',
|
||||
},
|
||||
{
|
||||
name: '侧边菜单 + 顶部栏布局',
|
||||
tip: '顶部栏仅用于显示全局信息或操作,不包含菜单。',
|
||||
type: 'sidebar-topbar',
|
||||
},
|
||||
]);
|
||||
|
||||
function activeClass(theme: string): string[] {
|
||||
|
|
|
@ -45,7 +45,7 @@ function defineOverridesPreferences(preferences: DeepPartial<Preferences>) {
|
|||
// 检查更新的时间间隔,单位为分钟
|
||||
checkUpdatesInterval: 1,
|
||||
// 开启布局设置按钮
|
||||
enablePreferences: false,
|
||||
enablePreferences: true,
|
||||
enableRefreshToken: false,
|
||||
},
|
||||
theme: {
|
||||
|
@ -59,6 +59,9 @@ function defineOverridesPreferences(preferences: DeepPartial<Preferences>) {
|
|||
semiDarkHeader: false,
|
||||
semiDarkSidebar: true,
|
||||
},
|
||||
header: {
|
||||
height: 50,
|
||||
},
|
||||
footer: {
|
||||
enable: false,
|
||||
fixed: false,
|
||||
|
|
Loading…
Reference in New Issue