<script setup lang="ts">
import { ref, onMounted } from 'vue'
import EmblaCarousel from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
const emblaNode = ref<HTMLElement | null>(null)
const emblaApi = ref<any>(null)
const currentIndex = ref(0)
const scrollPrev = () => emblaApi.value?.scrollPrev()
const scrollNext = () => emblaApi.value?.scrollNext()
onMounted(() => {
if (emblaNode.value) {
emblaApi.value = EmblaCarousel(
emblaNode.value,
{
loop: true,
align: 'center',
containScroll: false,
dragFree: false
},
[
Autoplay({
delay: 2000,
stopOnInteraction: false
})
]
)
emblaApi.value.on('select', () => {
currentIndex.value = emblaApi.value?.selectedScrollSnap() || 0
})
}
})
</script>
<template>
<div class="embla">
<div class="embla__viewport" ref="emblaNode">
<div class="embla__container">
<div class="embla__slide" v-for="n in 5" :key="n">
<div class="embla__slide__number">
Slide {{ n }}
</div>
</div>
</div>
</div>
<div class="embla__controls">
<button class="embla__button" @click="scrollPrev">
<span class="embla__button__text">Prev</span>
</button>
<div class="embla__dots">
<button
v-for="n in 5"
:key="n"
class="embla__dot"
:class="{ 'embla__dot--selected': currentIndex === n - 1 }"
@click="emblaApi?.scrollTo(n - 1)"
/>
</div>
<button class="embla__button" @click="scrollNext">
<span class="embla__button__text">Next</span>
</button>
</div>
</div>
</template>
<style lang="scss" scoped>
.embla {
max-width: 48rem;
margin: auto;
&__viewport {
overflow: hidden;
}
&__container {
display: flex;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
}
&__slide {
position: relative;
flex: 0 0 100%; // 关键:设置每个 slide 宽度为 100%
min-width: 0;
&__number {
display: flex;
align-items: center;
justify-content: center;
height: 20rem;
font-size: 2rem;
background-color: #f5f5f5;
border-radius: 0.5rem;
}
}
&__controls {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem;
}
&__button {
padding: 0.5rem 1rem;
color: white;
cursor: pointer;
background-color: #4a5568;
border: none;
border-radius: 0.25rem;
&:hover {
background-color: #2d3748;
}
}
&__dots {
display: flex;
gap: 0.5rem;
padding: 0 1rem;
}
&__dot {
width: 0.75rem;
height: 0.75rem;
cursor: pointer;
background-color: #e2e8f0;
border: none;
border-radius: 50%;
padding: 0;
&--selected {
background-color: #4a5568;
}
}
}
</style>