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' 的同时需要配置的
 
posted @ 2024-11-04 15:51  芝麻小仙女  阅读(977)  评论(0)    收藏  举报