vue2轮播图组件
子组件
<template><div class="swiper-container" @touchstart="handleTouchStart"@touchend="handleTouchEnd"><!-- 轮播内容 --><div class="swiper-wrapper" :style="wrapperStyle"><div v-for="(item, index) in slides" :key="index"class="swiper-slide"><img :src="item.image"><h2>{{ item.title }}</h2></div></div><!-- 分页器 --><div class="swiper-pagination"><span v-for="n in slides.length" :key="n":class="{ active: currentIndex === n - 1 }"@click="goTo(n - 1)"></span></div><!-- 导航按钮 --><div class="swiper-button-prev" @click="prev"></div><div class="swiper-button-next" @click="next"></div></div>
</template><script>
export default {props: {slides: {type: Array,required: true},autoplay: {type: Boolean,default: true},interval: {type: Number,default: 3000}},data() {return {currentIndex: 0,startX: 0,timer: null}},computed: {wrapperStyle() {return {transform: `translateX(-${this.currentIndex * 100}%)`,transition: 'transform 0.3s ease'}}},mounted() {this.startAutoplay()console.log('this.slides ',this.slides);},beforeDestroy() {this.clearAutoplay()},methods: {startAutoplay() {if (this.autoplay) {this.timer = setInterval(this.next, this.interval)}},clearAutoplay() {if (this.timer) {clearInterval(this.timer)this.timer = null}},handleTouchStart(e) {this.startX = e.touches[0].clientXthis.clearAutoplay()},handleTouchEnd(e) {const endX = e.changedTouches[0].clientXconst diffX = endX - this.startXif (Math.abs(diffX) > 50) { // 滑动阈值diffX > 0 ? this.prev() : this.next()}this.startAutoplay()},goTo(index) {if (index >= 0 && index < this.slides.length) {this.currentIndex = index}},prev() {this.currentIndex = this.currentIndex > 0 ? this.currentIndex - 1 : this.slides.length - 1},next() {this.currentIndex = this.currentIndex < this.slides.length - 1 ? this.currentIndex + 1 : 0}}
}
</script><style scoped>
.swiper-container {position: relative;overflow: hidden;width: 100%;height: 400px;
}.swiper-wrapper {display: flex;height: 100%;
}.swiper-slide {flex-shrink: 0;width: 100%;height: 100%;}.swiper-pagination {position: absolute;bottom: 10px;width: 100%;display: flex;justify-content: center;gap: 8px;
}.swiper-pagination span {width: 8px;height: 8px;border-radius: 50%;background: rgba(255,255,255,0.5);cursor: pointer;transition: background 0.3s;
}.swiper-pagination span.active {background: #fff;
}.swiper-button-prev,
.swiper-button-next {position: absolute;top: 50%;transform: translateY(-50%);width: 40px;height: 40px;background: rgba(0,0,0,0.3);cursor: pointer;border-radius: 50%;display: flex;align-items: center;justify-content: center;color: white;
}.swiper-button-prev::after,
.swiper-button-next::after {content: '';width: 10px;height: 10px;border: 2px solid white;border-width: 2px 2px 0 0;
}.swiper-button-prev {left: 10px;transform: rotate(-135deg);
}.swiper-button-next {right: 10px;transform: rotate(45deg);
}.swiper-button-prev::after,
.swiper-button-next::after {margin-top: 0px;
}
</style>
父组件
<template><div><Swiper :slides="slides" :interval="5000"></Swiper></div>
</template><script>
import Swiper from '../components/swiperV.vue'export default {name: 'VueMainjsswiper',components: { Swiper },data() {return {slides: [{ image: require("@/assets/avtor.webp"), title: 'Slide 1' },{ image: require("@/assets/avtor.webp"), title: 'Slide 2' },{ image: require("@/assets/avtor.webp"), title: 'Slide 3' }]}},mounted() {console.log('Slides Data:', JSON.stringify(this.slides))
}
}
</script>
运行效果: