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