125 lines
2.8 KiB
Vue
125 lines
2.8 KiB
Vue
|
<template>
|
||
|
<view class="carousel-container">
|
||
|
<!-- 轮播主体 -->
|
||
|
<swiper
|
||
|
class="swiper-box"
|
||
|
:current="currentIndex"
|
||
|
@change="onSwiperChange"
|
||
|
circular
|
||
|
>
|
||
|
<swiper-item v-for="(item, index) in images" :key="index" class="swiper-item">
|
||
|
<image :src="item" class="swiper-image" mode="aspectFill" />
|
||
|
</swiper-item>
|
||
|
</swiper>
|
||
|
|
||
|
<!-- 控制按钮 -->
|
||
|
<view class="nav-buttons">
|
||
|
<view class="btn prev" @click="switchSlide(-1)">
|
||
|
<image style="width: 50rpx;height: 50rpx;" src="/static/detail/left.png"></image>
|
||
|
</view>
|
||
|
<view class="btn next" @click="switchSlide(1)">
|
||
|
<image style="width: 50rpx;height: 50rpx;" src="/static/detail/right.png"></image>
|
||
|
</view>
|
||
|
</view>
|
||
|
|
||
|
<!-- 自定义指示器 -->
|
||
|
<!-- <view class="dots">
|
||
|
<text
|
||
|
v-for="(dot, idx) in images.length"
|
||
|
:key="idx"
|
||
|
:class="['dot', { active: currentIndex === idx }]"
|
||
|
/>
|
||
|
</view> -->
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
export default {
|
||
|
props: {
|
||
|
images: { type: Array, default: () => [] } // 接收外部图片数组
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
currentIndex: 0
|
||
|
};
|
||
|
},
|
||
|
methods: {
|
||
|
// 滑动切换回调
|
||
|
onSwiperChange(e) {
|
||
|
this.currentIndex = e.detail.current;
|
||
|
},
|
||
|
// 按钮切换逻辑
|
||
|
switchSlide(step) {
|
||
|
const total = this.images.length;
|
||
|
let newIndex = this.currentIndex + step;
|
||
|
|
||
|
if (newIndex < 0) newIndex = total - 1; // 循环向前
|
||
|
else if (newIndex >= total) newIndex = 0; // 循环向后
|
||
|
|
||
|
this.currentIndex = newIndex;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
</script>
|
||
|
<style lang="scss" scoped>
|
||
|
.carousel-container {
|
||
|
position: relative;
|
||
|
height: 400rpx;
|
||
|
}
|
||
|
|
||
|
.swiper-box {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
.swiper-item{
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: center;
|
||
|
}
|
||
|
.swiper-image {
|
||
|
width: 200rpx;
|
||
|
height: 200rpx;
|
||
|
border-radius: 16rpx;
|
||
|
}
|
||
|
|
||
|
.nav-buttons {
|
||
|
position: absolute;
|
||
|
top: 50%;
|
||
|
transform: translateY(-50%);
|
||
|
width: 100%;
|
||
|
display: flex;
|
||
|
justify-content: space-between;
|
||
|
|
||
|
.btn {
|
||
|
width: 60rpx;
|
||
|
height: 60rpx;
|
||
|
// border-radius: 50%;
|
||
|
// background: rgba(0,0,0,0.3);
|
||
|
color: white;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: center;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.dots {
|
||
|
position: absolute;
|
||
|
bottom: 20rpx;
|
||
|
width: 100%;
|
||
|
display: flex;
|
||
|
justify-content: center;
|
||
|
|
||
|
.dot {
|
||
|
width: 12rpx;
|
||
|
height: 12rpx;
|
||
|
border-radius: 50%;
|
||
|
background: rgba(255,255,255,0.5);
|
||
|
margin: 0 8rpx;
|
||
|
|
||
|
&.active {
|
||
|
background: #007AFF;
|
||
|
transform: scale(1.2);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</style>
|