12345678910111213141516171819202122232425262728293031323334353637383940414243 |
- <script setup lang="ts" generic="T extends Object">
- const props = withDefaults(defineProps<{ items?: T[]; dotColor?: string }>(), {
- items: () => [],
- dotColor: () => '#000',
- })
- const modelValue = defineModel({ type: Number, default: 0 })
- const handleSwiperChange = async ({ detail: { current } }) => {
- modelValue.value = current
- }
- </script>
- <template>
- <div class="w-full h-full relative">
- <swiper class="w-full h-full" autoplay :current="modelValue" @change="handleSwiperChange">
- <template v-for="(it, i) in items" :key="i">
- <swiper-item>
- <div class="w-full h-full swiper-item"><slot :item="it"></slot></div>
- </swiper-item>
- </template>
- </swiper>
- <div class="absolute flex gap-1 dots">
- <template v-for="(it, i) in items" :key="i">
- <div
- class="w-1 h-1 rounded-full"
- :class="`${modelValue === i ? `bg-active` : `opacity-50`}`"
- :style="{ background: dotColor }"
- ></div>
- </template>
- </div>
- </div>
- </template>
- <style scoped>
- .dots {
- bottom: 10px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 1000;
- }
- .bg-active {
- width: 30rpx;
- transition: width 0.3s ease-in-out;
- }
- </style>
|