bindbox-mini/components/activity/ActivityTabs.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>