Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 4m47s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 2s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
- TransactionDetail, CategoryBillPopup 移入 Transaction/ - BudgetTypeTabs 移入 Budget/ - GlassBottomNav, ModernEmpty 移入 Global/ - Icon, IconSelector, ClassifySelector 等 8 个通用组件移入 Common/ - 更新所有相关引用路径
181 lines
3.5 KiB
Vue
181 lines
3.5 KiB
Vue
<!--
|
||
PopupContainer V2 - 通用底部弹窗组件(采用 TransactionDetailSheet 样式风格)
|
||
|
||
## 与 V1 的区别
|
||
- V1 (PopupContainer.vue): 使用 Vant 主题变量,标准化布局,默认高度 80%
|
||
- V2 (PopupContainerV2.vue): 使用 Inter 字体,16px 圆角,纯白背景,更现代化的视觉风格
|
||
|
||
## 基础用法
|
||
<PopupContainerV2 v-model:show="show" title="标题">
|
||
<div class="content">内容区域</div>
|
||
<template #footer>
|
||
<van-button type="primary">确定</van-button>
|
||
</template>
|
||
</PopupContainerV2>
|
||
|
||
## Props
|
||
- show (Boolean, required): 控制弹窗显示/隐藏
|
||
- title (String, required): 标题文本
|
||
- height (String, default: 'auto'): 弹窗高度,支持 'auto', '80%', '500px' 等
|
||
- maxHeight (String, default: '85%'): 最大高度
|
||
|
||
## Slots
|
||
- default: 可滚动的内容区域(不提供默认 padding,由使用方控制)
|
||
- footer: 固定底部区域(操作按钮等)
|
||
|
||
## Events
|
||
- update:show: 弹窗显示/隐藏状态变更
|
||
-->
|
||
<template>
|
||
<van-popup
|
||
v-model:show="visible"
|
||
position="bottom"
|
||
:style="{
|
||
height: height === 'auto' ? maxHeight : height,
|
||
borderTopLeftRadius: '16px',
|
||
borderTopRightRadius: '16px'
|
||
}"
|
||
teleport="body"
|
||
@close="handleClose"
|
||
>
|
||
<div class="popup-container-v2">
|
||
<!-- 固定头部 -->
|
||
<div class="popup-header">
|
||
<h3 class="popup-title">
|
||
{{ title }}
|
||
</h3>
|
||
<van-icon
|
||
name="cross"
|
||
class="popup-close"
|
||
@click="handleClose"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 可滚动内容区域 -->
|
||
<div class="popup-content">
|
||
<slot />
|
||
</div>
|
||
|
||
<!-- 固定底部 -->
|
||
<div
|
||
v-if="hasFooter"
|
||
class="popup-footer"
|
||
>
|
||
<slot name="footer" />
|
||
</div>
|
||
</div>
|
||
</van-popup>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, useSlots } from 'vue'
|
||
|
||
const props = defineProps({
|
||
show: {
|
||
type: Boolean,
|
||
required: true
|
||
},
|
||
title: {
|
||
type: String,
|
||
required: true
|
||
},
|
||
height: {
|
||
type: String,
|
||
default: 'auto'
|
||
},
|
||
maxHeight: {
|
||
type: String,
|
||
default: '85%'
|
||
}
|
||
})
|
||
|
||
const emit = defineEmits(['update:show'])
|
||
|
||
const slots = useSlots()
|
||
|
||
// 双向绑定
|
||
const visible = computed({
|
||
get: () => props.show,
|
||
set: (value) => emit('update:show', value)
|
||
})
|
||
|
||
// 判断是否有 footer 插槽
|
||
const hasFooter = computed(() => !!slots.footer)
|
||
|
||
// 关闭弹窗
|
||
const handleClose = () => {
|
||
visible.value = false
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.popup-container-v2 {
|
||
background: #ffffff;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
// 固定头部
|
||
.popup-header {
|
||
flex-shrink: 0;
|
||
padding: 24px;
|
||
padding-bottom: 16px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.popup-title {
|
||
font-family: Inter, sans-serif;
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #09090b;
|
||
margin: 0;
|
||
}
|
||
|
||
.popup-close {
|
||
font-size: 24px;
|
||
color: #71717a;
|
||
cursor: pointer;
|
||
transition: opacity 0.2s;
|
||
|
||
&:active {
|
||
opacity: 0.7;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 可滚动内容区域
|
||
.popup-content {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
-webkit-overflow-scrolling: touch;
|
||
// 不提供默认 padding,由使用方控制
|
||
}
|
||
|
||
// 固定底部
|
||
.popup-footer {
|
||
flex-shrink: 0;
|
||
padding: 24px;
|
||
padding-top: 16px;
|
||
}
|
||
|
||
// 暗色模式
|
||
@media (prefers-color-scheme: dark) {
|
||
.popup-container-v2 {
|
||
background: #18181b;
|
||
}
|
||
|
||
.popup-header {
|
||
.popup-title {
|
||
color: #fafafa;
|
||
}
|
||
|
||
.popup-close {
|
||
color: #a1a1aa;
|
||
}
|
||
}
|
||
}
|
||
</style>
|