117 lines
2.3 KiB
Vue
117 lines
2.3 KiB
Vue
<template>
|
|
<view class="section-container animate-enter" :class="staggerClass">
|
|
<!-- Modern Tabs - 与原始设计一致 -->
|
|
<view class="modern-tabs">
|
|
<view
|
|
v-for="tab in tabs"
|
|
:key="tab.key"
|
|
class="tab-item"
|
|
:class="{ active: modelValue === tab.key }"
|
|
@tap="$emit('update:modelValue', tab.key)"
|
|
>
|
|
{{ tab.label }}
|
|
<view v-if="modelValue === tab.key" class="active-dot"></view>
|
|
</view>
|
|
</view>
|
|
|
|
<slot :name="modelValue"></slot>
|
|
<slot></slot>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: String,
|
|
default: 'pool'
|
|
},
|
|
tabs: {
|
|
type: Array,
|
|
default: () => [
|
|
{ key: 'pool', label: '本机奖池' },
|
|
{ key: 'records', label: '购买记录' }
|
|
]
|
|
},
|
|
stagger: {
|
|
type: Number,
|
|
default: 1
|
|
}
|
|
})
|
|
|
|
defineEmits(['update:modelValue'])
|
|
|
|
const staggerClass = computed(() => `stagger-${props.stagger}`)
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
/* Section Container - 与原始设计一致 */
|
|
.section-container {
|
|
margin: 0 $spacing-lg $spacing-lg;
|
|
background: rgba(255, 255, 255, 0.9);
|
|
border-radius: $radius-xl;
|
|
padding: $spacing-lg;
|
|
box-shadow: $shadow-sm;
|
|
backdrop-filter: blur(10rpx);
|
|
}
|
|
|
|
/* Modern Tabs - 与原始设计完全一致 */
|
|
.modern-tabs {
|
|
display: flex;
|
|
background: $bg-secondary;
|
|
padding: 8rpx;
|
|
border-radius: $radius-lg;
|
|
margin-bottom: $spacing-lg;
|
|
}
|
|
|
|
.tab-item {
|
|
flex: 1;
|
|
text-align: center;
|
|
padding: $spacing-md 0;
|
|
font-size: $font-md;
|
|
color: $text-sub;
|
|
border-radius: $radius-md;
|
|
font-weight: 600;
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
position: relative;
|
|
|
|
&.active {
|
|
background: #FFFFFF;
|
|
color: $brand-primary;
|
|
box-shadow: $shadow-sm;
|
|
}
|
|
}
|
|
|
|
.active-dot {
|
|
width: 8rpx;
|
|
height: 8rpx;
|
|
background: $brand-primary;
|
|
border-radius: 50%;
|
|
position: absolute;
|
|
bottom: 8rpx;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
/* 入场动画 */
|
|
.animate-enter {
|
|
animation: slideUp 0.5s ease-out both;
|
|
}
|
|
|
|
.stagger-1 { animation-delay: 0.1s; }
|
|
.stagger-2 { animation-delay: 0.2s; }
|
|
.stagger-3 { animation-delay: 0.3s; }
|
|
|
|
@keyframes slideUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20rpx);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|