|
|
@@ -1,12 +1,50 @@
|
|
|
<script setup lang="ts">
|
|
|
+/**
|
|
|
+ * PageMain 页面主容器组件
|
|
|
+ *
|
|
|
+ * 用于包裹页面内容的通用容器组件,提供标题栏、内容区域和折叠功能
|
|
|
+ *
|
|
|
+ * @component
|
|
|
+ * @example
|
|
|
+ * // 基础用法
|
|
|
+ * <PageMain title="页面标题">
|
|
|
+ * <!-- 页面内容 -->
|
|
|
+ * </PageMain>
|
|
|
+ *
|
|
|
+ * // 带自定义标题插槽
|
|
|
+ * <PageMain>
|
|
|
+ * <template #title>
|
|
|
+ * <div class="custom-title">自定义标题</div>
|
|
|
+ * </template>
|
|
|
+ * <!-- 页面内容 -->
|
|
|
+ * </PageMain>
|
|
|
+ */
|
|
|
defineOptions({
|
|
|
name: 'PageMain',
|
|
|
})
|
|
|
|
|
|
+/**
|
|
|
+ * Props 定义
|
|
|
+ */
|
|
|
const props = withDefaults(
|
|
|
defineProps<{
|
|
|
+ /**
|
|
|
+ * 页面标题(字符串形式)
|
|
|
+ * 如果同时提供 title 属性和 title 插槽,插槽优先级更高
|
|
|
+ */
|
|
|
title?: string
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否折叠状态
|
|
|
+ * true: 容器折叠为指定高度,显示展开按钮
|
|
|
+ * false: 容器正常显示
|
|
|
+ */
|
|
|
collaspe?: boolean
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 折叠状态下的高度
|
|
|
+ * 仅在 collaspe 为 true 时生效
|
|
|
+ */
|
|
|
height?: string
|
|
|
}>(),
|
|
|
{
|
|
|
@@ -16,40 +54,95 @@ const props = withDefaults(
|
|
|
},
|
|
|
)
|
|
|
|
|
|
+/**
|
|
|
+ * 是否存在自定义标题插槽
|
|
|
+ */
|
|
|
const titleSlot = !!useSlots().title
|
|
|
|
|
|
+/**
|
|
|
+ * 当前折叠状态(响应式)
|
|
|
+ */
|
|
|
const isCollaspe = ref(props.collaspe)
|
|
|
+
|
|
|
+/**
|
|
|
+ * 展开容器方法
|
|
|
+ * 将折叠状态设置为 false,恢复容器正常高度
|
|
|
+ */
|
|
|
function unCollaspe() {
|
|
|
isCollaspe.value = false
|
|
|
}
|
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
|
+/**
|
|
|
+ * 主内容容器样式
|
|
|
+ * 高度设为 100% 以撑满父容器
|
|
|
+ */
|
|
|
.main-container {
|
|
|
height: 100%;
|
|
|
- padding: 24px;
|
|
|
}
|
|
|
-.page-main{
|
|
|
- border-radius: 6px ;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 页面主容器样式
|
|
|
+ * 圆角 6px
|
|
|
+ */
|
|
|
+.page-main {
|
|
|
+ border-radius: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 折叠区域样式
|
|
|
+ * 渐变背景 + 展开按钮
|
|
|
+ */
|
|
|
+.collaspe {
|
|
|
+ background: linear-gradient(to bottom, transparent, var(--g-container-bg));
|
|
|
+}
|
|
|
+
|
|
|
+.pageheader {
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ span {
|
|
|
+ font-size: 18px;
|
|
|
+ color: #333;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tag {
|
|
|
+ width: 4px;
|
|
|
+ height: 18px;
|
|
|
+ background: #0083FF;
|
|
|
+ border-radius: 10px 10px 10px 10px;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|
|
|
<template>
|
|
|
- <div
|
|
|
- class="page-main relative m-[24px] flex flex-col bg-[var(--g-container-bg)] transition-background-color-300" :class="{
|
|
|
- 'of-hidden': isCollaspe,
|
|
|
+ <!-- 页面主容器 -->
|
|
|
+ <div class="page-main relative m-[24px] flex flex-col bg-[var(--g-container-bg)] transition-background-color-300"
|
|
|
+ :class="{
|
|
|
+ 'of-hidden': isCollaspe, // 折叠时隐藏溢出内容
|
|
|
}" :style="{
|
|
|
- height: isCollaspe ? height : '',
|
|
|
- }"
|
|
|
- >
|
|
|
- <div v-if="titleSlot || title" class="title-container border-b-1 border-b-[var(--g-bg)] border-b-solid px-5 py-4 transition-border-color-300">
|
|
|
- <slot name="title">
|
|
|
- {{ title }}
|
|
|
- </slot>
|
|
|
- </div>
|
|
|
- <div class="main-container p-5" style="">
|
|
|
+ height: isCollaspe ? height : '', // 折叠时设置指定高度
|
|
|
+ }">
|
|
|
+ <!-- 主内容区域 -->
|
|
|
+ <div class="main-container p-6" :class="{
|
|
|
+ 'pt-[12px]': title, // 标题栏存在时添加顶部间距
|
|
|
+ }">
|
|
|
+ <!-- 标题栏区域 -->
|
|
|
+ <div v-if="titleSlot || title"
|
|
|
+ class="title-container border-b-1 border-b-[#eee] pb-[12px] border-b-solid transition-border-color-300 pageheader flex items-center mb-[20px]">
|
|
|
+ <!-- 标题插槽:优先级高于 title 属性 -->
|
|
|
+ <slot name="title">
|
|
|
+ <div class="tag"></div>
|
|
|
+ <span class="ml-[10px]">{{ title }}</span>
|
|
|
+ </slot>
|
|
|
+ </div>
|
|
|
+ <!-- 默认插槽:页面内容 -->
|
|
|
<slot />
|
|
|
</div>
|
|
|
- <div v-if="isCollaspe" class="collaspe absolute bottom-0 w-full cursor-pointer from-transparent to-[var(--g-container-bg)] bg-gradient-to-b pb-2 pt-10 text-center" @click="unCollaspe">
|
|
|
+
|
|
|
+ <!-- 折叠状态下的展开按钮 -->
|
|
|
+ <div v-if="isCollaspe" class="collaspe absolute bottom-0 w-full cursor-pointer pb-2 pt-10 text-center"
|
|
|
+ @click="unCollaspe">
|
|
|
<SvgIcon name="i-ep:arrow-down" class="text-xl op-30 transition-opacity hover-op-100" />
|
|
|
</div>
|
|
|
</div>
|
|
|
-</template>
|
|
|
+</template>
|