刚开始做的时候网上找了一下,没有左右大小不一的对应解决方案,所以就自己捣鼓了一下,也花了写时间,在这儿给大家做一下分享
官方文档
效果展示
<template>
<div class="home_carousel">
<Swiper
ref="swiperInstance"
class="carousel_list_container"
:options="swiperOption"
@slide-change="handleHSwiperSlideChange"
>
<SwiperSlide v-for="(item, index) in carousels" :key="index" class="carousel_list">
<a
:href="item.url || 'javascript:void(0)'"
:class="item.url && 'link'"
class="carousel_item"
@click="handleClick(item.url)"
>
<img :src="item.image" />
</a>
</SwiperSlide>
</Swiper>
<div class="carousel_indicator">
<div class="indicator_line"></div>
<ul class="dots">
<li v-for="(item, index) in carousels" :key="item.id" class="dot" :class="{ active: activeIndex === index }">
<IconCarouselActive v-if="activeIndex === index" class="icon_carousel_active" />
</li>
</ul>
</div>
</div>
</template>
<script lang="ts">
import SwiperClass from 'swiper'
import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'
import IconCarouselActive from '~/assets/svg/homepage/icon_carousel_active.svg?inline'
const swiperOption = {
loop: true, //循环
autoplay: { //自动播放
delay: 2000,
stopOnLastSlide: false,
disableOnInteraction: false,
reverseDirection: false,
waitForTransition: true,
},
spaceBetween: 5, //左右间距
slidesPerView: 'auto', //这必须要加,否则返回第一页的时候,右边模块会缺失
}
</script>
<style lang="scss" scoped>
@import '~/assets/css/mixin.scss';
.home_carousel {
position: relative;
overflow: hidden;
//自定义分页器的样式
.carousel_indicator {
position: absolute;
bottom: 5rpx;
height: 10rpx;
left: 50%;
transform: translateX(-50%);
z-index: 1;
.indicator_line {
position: absolute;
left: -35rpx;
right: -35rpx;
top: 4rpx;
height: 1px;
background: linear-gradient(90deg, rgba(255, 255, 255, 0) -2.5%, #ffffff 50.22%, rgba(255, 255, 255, 0) 97.5%);
filter: drop-shadow(0px 0px 8px rgba(0, 0, 0, 0.1));
}
.dots {
display: flex;
align-items: center;
@include resetListStyle();
.dot {
width: 4rpx;
height: 4rpx;
background-color: #ffffff;
flex: 1 0 auto;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
border-radius: 50%;
position: relative;
&:not(:first-child) {
margin-left: 10rpx;
}
&.active {
width: 10rpx;
height: 10rpx;
background-color: transparent;
}
.icon_carousel_active {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
}
}
}
.swiper-container {
overflow: visible !important;
width: 274rpx;
height: 100rpx;
}
.swiper-container .swiper-wrapper .swiper-slide {
border-radius: 10rpx;
}
.swiper-container .swiper-wrapper .swiper-slide img {
width: 274rpx;
height: 100%;
border-radius: 4rpx;
}
//左右宽度不一样的重点样式
.swiper-container .swiper-wrapper .swiper-slide-active {
position: relative;
left: -20rpx;
width: 274rpx;
}
.swiper-container .swiper-wrapper .swiper-slide-prev {
position: relative;
left: -20rpx;
}
.swiper-container .swiper-wrapper .swiper-slide-next {
position: relative;
left: -20rpx;
}
</style>