|
@@ -1,5 +1,15 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { computed, nextTick, onMounted, ref, useTemplateRef } from 'vue';
|
|
|
|
|
|
+import {
|
|
|
|
+ computed,
|
|
|
|
+ nextTick,
|
|
|
|
+ onMounted,
|
|
|
|
+ ref,
|
|
|
|
+ type StyleValue,
|
|
|
|
+ useTemplateRef,
|
|
|
|
+} from 'vue';
|
|
|
|
+
|
|
|
|
+import { preferences } from '@vben-core/preferences';
|
|
|
|
+import { cn } from '@vben-core/shared/utils';
|
|
|
|
|
|
interface Props {
|
|
interface Props {
|
|
title?: string;
|
|
title?: string;
|
|
@@ -9,6 +19,10 @@ interface Props {
|
|
* 根据content可见高度自适应
|
|
* 根据content可见高度自适应
|
|
*/
|
|
*/
|
|
autoContentHeight?: boolean;
|
|
autoContentHeight?: boolean;
|
|
|
|
+ /** 头部固定 */
|
|
|
|
+ fixedHeader?: boolean;
|
|
|
|
+ headerClass?: string;
|
|
|
|
+ footerClass?: string;
|
|
}
|
|
}
|
|
|
|
|
|
defineOptions({
|
|
defineOptions({
|
|
@@ -20,6 +34,7 @@ const {
|
|
description = '',
|
|
description = '',
|
|
autoContentHeight = false,
|
|
autoContentHeight = false,
|
|
title = '',
|
|
title = '',
|
|
|
|
+ fixedHeader = false,
|
|
} = defineProps<Props>();
|
|
} = defineProps<Props>();
|
|
|
|
|
|
const headerHeight = ref(0);
|
|
const headerHeight = ref(0);
|
|
@@ -29,6 +44,17 @@ const shouldAutoHeight = ref(false);
|
|
const headerRef = useTemplateRef<HTMLDivElement>('headerRef');
|
|
const headerRef = useTemplateRef<HTMLDivElement>('headerRef');
|
|
const footerRef = useTemplateRef<HTMLDivElement>('footerRef');
|
|
const footerRef = useTemplateRef<HTMLDivElement>('footerRef');
|
|
|
|
|
|
|
|
+const headerStyle = computed<StyleValue>(() => {
|
|
|
|
+ return fixedHeader
|
|
|
|
+ ? {
|
|
|
|
+ position: 'sticky',
|
|
|
|
+ zIndex: 200,
|
|
|
|
+ top:
|
|
|
|
+ preferences.header.mode === 'fixed' ? 'var(--vben-header-height)' : 0,
|
|
|
|
+ }
|
|
|
|
+ : undefined;
|
|
|
|
+});
|
|
|
|
+
|
|
const contentStyle = computed(() => {
|
|
const contentStyle = computed(() => {
|
|
if (autoContentHeight) {
|
|
if (autoContentHeight) {
|
|
return {
|
|
return {
|
|
@@ -69,7 +95,14 @@ onMounted(() => {
|
|
$slots.extra
|
|
$slots.extra
|
|
"
|
|
"
|
|
ref="headerRef"
|
|
ref="headerRef"
|
|
- class="bg-card relative px-6 py-4"
|
|
|
|
|
|
+ :class="
|
|
|
|
+ cn(
|
|
|
|
+ 'bg-card relative px-6 py-4',
|
|
|
|
+ headerClass,
|
|
|
|
+ fixedHeader ? 'border-border border-b' : '',
|
|
|
|
+ )
|
|
|
|
+ "
|
|
|
|
+ :style="headerStyle"
|
|
>
|
|
>
|
|
<slot name="title">
|
|
<slot name="title">
|
|
<div v-if="title" class="mb-2 flex text-lg font-semibold">
|
|
<div v-if="title" class="mb-2 flex text-lg font-semibold">
|
|
@@ -95,7 +128,12 @@ onMounted(() => {
|
|
<div
|
|
<div
|
|
v-if="$slots.footer"
|
|
v-if="$slots.footer"
|
|
ref="footerRef"
|
|
ref="footerRef"
|
|
- class="bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4"
|
|
|
|
|
|
+ :class="
|
|
|
|
+ cn(
|
|
|
|
+ footerClass,
|
|
|
|
+ 'bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4',
|
|
|
|
+ )
|
|
|
|
+ "
|
|
>
|
|
>
|
|
<slot name="footer"></slot>
|
|
<slot name="footer"></slot>
|
|
</div>
|
|
</div>
|