需求:
英雄展示页面提供纵向头像滚动切换功能,需要支持循环滚动、拖动切换、前后按钮切换、点击头像图标切换等功能。
代码:
<div :class="$style.swiperBox"><swiperref="heroSwiper":options="swiperOptions":class="$style.swiper"@slideChange="slideChange"><swiper-slidev-for="(el, index) in imageUrl":key="index":data-id="index":class="$style.swiperSlide"><divclass="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的progressgrabCursor: true,pagination: false,slideToClickedSlide: true,// loopedSlides: 9,loopAdditionalSlides: 5, // loop模式下会在slides前后复制若干个slide,前后复制的个数不会大于原来的总个数,默认为0,前后各复制1个,其他取值前后各+1navigation: {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);// },},
以及通过这次需求学到了很重要的配置项:loopAdditionalSlides。有了这个视口中的虚拟元素也是可以触发了,但不明白为什么明明默认0(前后各复制1个)可实际效果中紧跟在数组首尾的元素也无法点击,大概还是我太菜了吧(晕倒在地)
之前使用loopedSlides死活有问题,看文档描述没什么大区别,最后才注意到这个参数是在loop模式下规定
slidesPerview:'auto'
的同时需要配置的,而我们的slidesPerView(同屏元素个数)是5,也许这就是关键区别?(停止思考)【真是看的时候嫌文档字多,真写到细节了恨不得文档再多写点……】