记录一次使用swiper的loop循环的问题

2,564 阅读2分钟

这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

前言

最近在做公司的春节h5活动,里面有个轮播,然后我是使用了swiper。这个主要是用来渲染轮播图或者幻灯片的库。

我们用的是swiper5

使用swiper不难,官方有使用文档

我们是用的vue,在vue里面使用swiper

  1. 引入swiper,然后在mounted钩子函数里面实例化(因为实例化需要传入dom的类名,vue在mounted钩子函数dom才挂载好)

  2. 实例化的时候的需要传入2个参数,一个是dom的类名,一个是swiper的配置。

  3. 我们swiper的配置上加了loop:true,可以一直循环使用。

  4. 然后就可以看效果了。

具体的代码如下:

  <div id="app">
    <button @click="changeText">改变</button>
    <div class="swiper-container">
      <div class="swiper-wrapper">
        <div
          class="swiper-slide"
          v-for="(item, i) in list"
          :key="i"
        >
          <div>text的内容:{{text}}</div>
          <img
            :src="item.img"
            alt=""
          >
        </div>
      </div>
    </div>
  </div>
  
import Swiper from 'swiper'
import 'swiper/css/swiper.min.css'
export default {
  name: 'App',
  data () {
    return {
      text: '答案',
      list: [{
        img: 'https://image.yqmh.com/mh/82324.jpg-300x400.webp'
      }, {
        img: 'https://image.yqmh.com/mh/108393.jpg-300x400.webp'
      }, {
        img: 'https://image.yqmh.com/mh/9680.jpg-300x400.webp'
      }],
      swiperOptions: {
        slidesPerView: 'auto',
        // // active slide是否居中显示
        centeredSlides: true,
        // // 是否循环显示
        loop: true,
        effect: 'coverflow',
        coverflowEffect: {
        }
      }
    }
  },
  methods: {
    changeText () {
      this.text = 'cp3'
    }
  },
  mounted () {
    /* eslint-disable no-new */
    new Swiper('.swiper-container', this.swiperOptions)
  }
}

效果如下:

QQ20220126-233532-HD.gif

咋一看,没什么问题,就是正常的轮播切换。

问题

但是我们是有个需求,单击图片需要加上选中的效果。这个就需要定义个变量,代表当前的点击的索引,点击图片就把当前的索引赋值给它,然后在template遍历整个图片的时候判断哪个索引和当前索引相等,相等就加上选中的效果。

这个需求不难,很容易就写好。但是我发现有个问题,就是切换轮播的时候点击的索引还会被重置成初始值,导致选中的效果没选中。

我模拟一下:

我上面有个按钮,改变,然后我给它加上changeText方法,点击的时候把text变成cp3

QQ20220127-234344-HD.gif

可以看到,点击后text后变成了cp3,但是切换swiper后text又变成了答案

然后我去看vue的data数据,索引确实变了,但是dom上面确实没变。

分析

我仔细一想,应该是跟loop模式有关。

因为swiper的loop模式会把当前swiper前后的swiper复制几份。然后复制的swiper是提前复制好的dom,不会动态去取改变后的索引。所以导致复制的swiper还是旧的索引。

解决

第一种方法:

可以使用vue-awesome-swiper, 这个是基于swiper的基础上,使用vue封装的swiper插件。 这个不会有这个问题。

第二种方法:

既然vue的data的数据已经变了,只是dom的索引没变,那么就可以通过dom操作去实现选中效果。比如document.querySelector('xxx').style.xxx = xxx

我选择了第二种。