|
@@ -21,6 +21,7 @@ defineOptions({
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
contentCompact: 'wide',
|
|
|
+ contentCompactWidth: 1200,
|
|
|
contentPadding: 0,
|
|
|
contentPaddingBottom: 0,
|
|
|
contentPaddingLeft: 0,
|
|
@@ -39,6 +40,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
layout: 'sidebar-nav',
|
|
|
sideCollapseWidth: 60,
|
|
|
sidebarCollapseShowTitle: false,
|
|
|
+ sidebarExtraCollapsedWidth: 60,
|
|
|
sidebarHidden: false,
|
|
|
sidebarMixedWidth: 80,
|
|
|
sidebarSemiDark: true,
|
|
@@ -62,16 +64,16 @@ const {
|
|
|
isScrolling,
|
|
|
y: scrollY,
|
|
|
} = useScroll(document);
|
|
|
+
|
|
|
const { y: mouseY } = useMouse({ type: 'client' });
|
|
|
|
|
|
// side是否处于hover状态展开菜单中
|
|
|
const sidebarExpandOnHovering = ref(false);
|
|
|
-// const sideHidden = ref(false);
|
|
|
const headerIsHidden = ref(false);
|
|
|
|
|
|
-const realLayout = computed(() => {
|
|
|
- return props.isMobile ? 'sidebar-nav' : props.layout;
|
|
|
-});
|
|
|
+const realLayout = computed(() =>
|
|
|
+ props.isMobile ? 'sidebar-nav' : props.layout,
|
|
|
+);
|
|
|
|
|
|
/**
|
|
|
* 是否全屏显示content,不需要侧边、底部、顶部、tab区域
|
|
@@ -98,7 +100,7 @@ const isMixedNav = computed(() => realLayout.value === 'mixed-nav');
|
|
|
/**
|
|
|
* 顶栏是否自动隐藏
|
|
|
*/
|
|
|
-const isHeaderAuto = computed(() => props.headerMode === 'auto');
|
|
|
+const isHeaderAutoMode = computed(() => props.headerMode === 'auto');
|
|
|
|
|
|
/**
|
|
|
* header区域高度
|
|
@@ -146,7 +148,7 @@ const sidebarEnableState = computed(() => {
|
|
|
/**
|
|
|
* 侧边区域离顶部高度
|
|
|
*/
|
|
|
-const sidePaddingTop = computed(() => {
|
|
|
+const sidebarMarginTop = computed(() => {
|
|
|
const { isMobile } = props;
|
|
|
return isMixedNav.value && !isMobile ? getHeaderHeight.value : 0;
|
|
|
});
|
|
@@ -182,10 +184,10 @@ const getSidebarWidth = computed(() => {
|
|
|
/**
|
|
|
* 获取扩展区域宽度
|
|
|
*/
|
|
|
-const getExtraWidth = computed(() => {
|
|
|
- const { sidebarWidth } = props;
|
|
|
+const sidebarExtraWidth = computed(() => {
|
|
|
+ const { sidebarExtraCollapsedWidth, sidebarWidth } = props;
|
|
|
|
|
|
- return sidebarExtraCollapse.value ? getSideCollapseWidth.value : sidebarWidth;
|
|
|
+ return sidebarExtraCollapse.value ? sidebarExtraCollapsedWidth : sidebarWidth;
|
|
|
});
|
|
|
|
|
|
/**
|
|
@@ -269,19 +271,29 @@ const mainStyle = computed(() => {
|
|
|
};
|
|
|
});
|
|
|
|
|
|
+// 计算 tabbar 的样式
|
|
|
const tabbarStyle = computed((): CSSProperties => {
|
|
|
let width = '';
|
|
|
let marginLeft = 0;
|
|
|
|
|
|
+ // 如果不是混合导航,tabbar 的宽度为 100%
|
|
|
if (!isMixedNav.value) {
|
|
|
width = '100%';
|
|
|
} else if (sidebarEnable.value) {
|
|
|
+ // 鼠标在侧边栏上时,且侧边栏展开时的宽度
|
|
|
+ const onHoveringWidth = sidebarExpandOnHover.value
|
|
|
+ ? props.sidebarWidth
|
|
|
+ : getSideCollapseWidth.value;
|
|
|
+
|
|
|
+ // 设置 marginLeft,根据侧边栏是否折叠来决定
|
|
|
marginLeft = sidebarCollapse.value
|
|
|
? getSideCollapseWidth.value
|
|
|
- : props.sidebarWidth;
|
|
|
+ : onHoveringWidth;
|
|
|
|
|
|
- width = `calc(100% - ${getSidebarWidth.value}px)`;
|
|
|
+ // 设置 tabbar 的宽度,计算方式为 100% 减去侧边栏的宽度
|
|
|
+ width = `calc(100% - ${sidebarCollapse.value ? getSidebarWidth.value : onHoveringWidth}px)`;
|
|
|
} else {
|
|
|
+ // 默认情况下,tabbar 的宽度为 100%
|
|
|
width = '100%';
|
|
|
}
|
|
|
|
|
@@ -300,7 +312,7 @@ const contentStyle = computed((): CSSProperties => {
|
|
|
fixed &&
|
|
|
!fullContent.value &&
|
|
|
!headerIsHidden.value &&
|
|
|
- (!isHeaderAuto.value || scrollY.value < headerWrapperHeight.value)
|
|
|
+ (!isHeaderAutoMode.value || scrollY.value < headerWrapperHeight.value)
|
|
|
? `${headerWrapperHeight.value}px`
|
|
|
: 0,
|
|
|
paddingBottom: `${footerEnable && footerFixed ? footerHeight : 0}px`,
|
|
@@ -333,7 +345,12 @@ const headerWrapperStyle = computed((): CSSProperties => {
|
|
|
*/
|
|
|
const sidebarZIndex = computed(() => {
|
|
|
const { isMobile, zIndex } = props;
|
|
|
- const offset = isMobile || isSideMode.value ? 1 : -1;
|
|
|
+ let offset = isMobile || isSideMode.value ? 1 : -1;
|
|
|
+
|
|
|
+ if (isMixedNav.value) {
|
|
|
+ offset += 1;
|
|
|
+ }
|
|
|
+
|
|
|
return zIndex + offset;
|
|
|
});
|
|
|
|
|
@@ -366,7 +383,12 @@ const showHeaderLogo = computed(() => {
|
|
|
watch(
|
|
|
() => props.isMobile,
|
|
|
(val) => {
|
|
|
- sidebarCollapse.value = val;
|
|
|
+ if (val) {
|
|
|
+ sidebarCollapse.value = true;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ immediate: true,
|
|
|
},
|
|
|
);
|
|
|
|
|
@@ -379,7 +401,7 @@ watch(
|
|
|
watch(
|
|
|
[() => props.headerMode, () => mouseY.value],
|
|
|
() => {
|
|
|
- if (!isHeaderAuto.value || isMixedNav.value || fullContent.value) {
|
|
|
+ if (!isHeaderAutoMode.value || isMixedNav.value || fullContent.value) {
|
|
|
return;
|
|
|
}
|
|
|
headerIsHidden.value = true;
|
|
@@ -434,10 +456,6 @@ function handleClickMask() {
|
|
|
sidebarCollapse.value = true;
|
|
|
}
|
|
|
|
|
|
-function handleToggleSidebar() {
|
|
|
- emit('toggleSidebar');
|
|
|
-}
|
|
|
-
|
|
|
function handleOpenMenu() {
|
|
|
sidebarCollapse.value = false;
|
|
|
}
|
|
@@ -456,12 +474,12 @@ function handleOpenMenu() {
|
|
|
v-model:extra-visible="sidebarExtraVisible"
|
|
|
:collapse-width="getSideCollapseWidth"
|
|
|
:dom-visible="!isMobile"
|
|
|
- :extra-width="getExtraWidth"
|
|
|
+ :extra-width="sidebarExtraWidth"
|
|
|
:fixed-extra="sidebarExpandOnHover"
|
|
|
:header-height="isMixedNav ? 0 : getHeaderHeight"
|
|
|
:is-sidebar-mixed="isSidebarMixedNav"
|
|
|
+ :margin-top="sidebarMarginTop"
|
|
|
:mixed-width="sidebarMixedWidth"
|
|
|
- :padding-top="sidePaddingTop"
|
|
|
:show="showSidebar"
|
|
|
:theme="sidebarFace.theme"
|
|
|
:width="getSidebarWidth"
|
|
@@ -506,7 +524,7 @@ function handleOpenMenu() {
|
|
|
:width="mainStyle.width"
|
|
|
:z-index="headerZIndex"
|
|
|
@open-menu="handleOpenMenu"
|
|
|
- @toggle-sidebar="handleToggleSidebar"
|
|
|
+ @toggle-sidebar="() => emit('toggleSidebar')"
|
|
|
>
|
|
|
<template v-if="showHeaderLogo" #logo>
|
|
|
<slot name="logo"></slot>
|