swiper插件同屏多个slide时在loop模式下点击切换失效的解决方案
需求:
英雄展示页面提供纵向头像滚动切换功能,需要支持循环滚动、拖动切换、前后按钮切换、点击头像图标切换等功能。
代码:
<div :class="$style.swiperBox">
<swiper
ref="heroSwiper"
:options="swiperOptions"
:class="$style.swiper"
@slideChange="slideChange"
>
<swiper-slide
v-for="(el, index) in imageUrl"
:key="index"
:data-id="index"
:class="$style.swiperSlide"
>
<div
class="hero_swiper_side"
:class="[
$style.swiperItem,
active === index && index === 0 ? $style.swiperItemFir : '',
active === index ? $style.swiperItemActive : '',
]"
>
<img :src="active === index ? el.l : el.s" />
<!-- @click="clickImg(index)" -->
</div>
</swiper-slide>
</swiper>
<div
:class="$style[`swiper-button-prev`]"
class="swiper-button-prev"
slot="button-prev"
></div>
<div
:class="$style[`swiper-button-next`]"
class="swiper-button-next"
slot="button-next"
></div>
</div>
swiper引入(使用了EffectCoverflow效果,可以理解为3D效果流):

import { Swiper, SwiperSlide } from "vue-awesome-swiper";
import Swiper2, { EffectCoverflow } from "swiper";
import "swiper/swiper.less";
Swiper2.use([EffectCoverflow]);
components: {
Swiper,
SwiperSlide,
},
swiper配置项:
swiperOptions: {
direction: "vertical",
// spaceBetween: 30,
slidesPerView: 5,
loop: true,
observer: true,
observerParents: true,
effect: "coverflow",
centeredSlides: true, //当前的active slide是否居中
watchSlidesProgress: true, //计算每个slide的progress
grabCursor: true,
pagination: false,
slideToClickedSlide: true,
// loopedSlides: 9,
loopAdditionalSlides: 5, // loop模式下会在slides前后复制若干个slide,前后复制的个数不会大于原来的总个数,默认为0,前后各复制1个,其他取值前后各+1
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
coverflowEffect: {
rotate: 0,
stretch: 0,
depth: 0,
modifier: 0,
slideShadows: false,
},
autoplay: false,
},
切换头像时需要触发角色信息的展示,这个操作配置在slideChange事件中:
slideChange() {
……
const index = this.$refs.heroSwiper.$swiper.realIndex;
this.active = index;
……
},
通过this.$refs.heroSwiper.$swiper.realIndex获取到当前元素(轮播中真实的index,即此元素在轮播数组中的index),即可进行对应操作。
如果点击事件配置在slide元素中,loop模式下必定会出现部分元素点击失效的问题,因为swiper会在真实元素前后复制多个虚拟slide元素进行拼接,保证轮播效果的流畅,但复制只是复制元素而不复制事件,因此会无法触发。所以我们最好在swiper配置项中就进行事件配置:
on: {
click: (event) => {
// 方案1 轮播效果有问题
let index =
event.clickedIndex - event.activeIndex + event.realIndex === 6
? 0
: event.clickedIndex - event.activeIndex + event.realIndex;
this.$refs.heroSwiper.$swiper.slideTo(index);
// 方案2 会出现中断的情况
// this.$refs.heroSwiper.$swiper.slideTo(event.clickedIndex);
// this.active = event.realIndex;
},
// slideChangeTransitionEnd() {
// this.slideToLoop(this.realIndex, 0, true);
// },
},
以及通过这次需求学到了swiper一个新的很重要的配置项:loopAdditionalSlides,默认0(前后各复制1个)
(如果使用loopedSlides这个参数,在loop模式下是规定
slidesPerview:'auto' 的同时需要配置的

浙公网安备 33010602011771号