Swiper 插件实现轮播图

1.swiper插件的使用步骤:

第一步:安装依赖 npm i swiper (可以根据需要选择对应版本)

第二步:引入相应的依赖包(swiper.js swiper.css)

第三步:页面中的结构务必要有

第四步:初始化 swiper 实例,new Swiper() ,给轮播图添加动态的效果

2.DOM结构如下:

<templete>
    <!--banner轮播-->
    <div class="swiper-container" id="mySwiper">
      <div class="swiper-wrapper">
        <!-- carousel 指轮播图 -->
        <div class="swiper-slide" v-for="(carousel) in bannerList" :key="carousel.id">
          <img :src="carousel.imgUrl" />
        </div>
       </div>
       <!-- 如果需要分页器 -->
      <div class="swiper-pagination"></div>
      <!-- 如果需要导航按钮 -->
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>
    </div>
</templete>
<script>
    // 引入 Swiper
    import Swiper from 'swiper'
    // 引入 Swiper 中CSS样式
    import 'swiper/css/swiper.css'
    import 'swiper/css/swiper.min.css'
</script>

3.创建swiper实例

接下来,创建swiper实例即可,主要有以下几种:

第一种(在updated中创建)【最好不用】:

updated() { // 在updated中可以实现功能,但是如果还有其他响应式数据,数据每一次变化 都要重新执行,所以轮播图不采用这个办法
  var mySwiper = new Swiper('.swiper-container', {
    loop: true, // 循环模式选项
    // 如果需要分页器
    pagination: {
      el: '.swiper-pagination',
    },
    // 如果需要前进后退按钮
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev',
    }
  })
},

第二种(在mounted中,配合定时器setTimeout使用)【不太推荐】:

这种方法就是 等我们的数据请求完毕后再创建swiper实例

mounted() { // mounted 组件挂载完毕,正常的结构(DOM)全有了
  // 派发actions 通知Vuex发送Ajax请求,将数据存储在仓库当中
  this.$store.dispatch('getBannerList');
  // 在 new Swiper 之前,页面中的结构必须有,直接把swiper实例放在mounted里面,不能实现功能(因为结构还不完整)
  // 为什么结构还不完整? 如果写在mounted中,在 new Swiper 之前,还未修改仓库中的bannerList数据
  // 因为dispatch当中涉及到异步语句,导致v-for遍历的时候 结构还没有完整 因此不行
  setTimeout(() => { // 不是最好的
    var mySwiper = new Swiper('.swiper-container', {
      loop: true, // 循环模式选项
      // 如果需要分页器
      pagination: {
        el: '.swiper-pagination',
        clickable: true // 小点点击可以切换
      },
      // 如果需要前进后退按钮
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      }
    });
  }, 2000)
},

第三种(watch + $nextTick 配合使用)【最好、推荐】:

我们可以使用watch监听bannerList轮播图列表属性,因为bannerList初始值为空,当它有数据时,我们就可以创建swiper对象。

但是只监听bannerList数据也无法实现功能,这是由于轮播图的html中有v-for的循环,我们是通过v-for遍历bannerList中的图片数据,然后展示。我们的watch只能保证在bannerList变化时创建swiper对象,但是并不能保证此时v-for已经执行完了。假如watch先监听到bannerList数据变化,执行回调函数创建了swiper对象,之后v-for才执行,这样也是无法渲染轮播图图片(因为swiper对象生效的前提是DOM结构已经渲染好了)。

所以最好的解决方法是:使用 watch 监听 bannerList 数据,配合 $nextTick 使用。(此时数据bannerList已经有了,且v-for已经渲染完毕)

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

watch: {
  // 监听bannerList数据的变化。因为这条数据发生过变化---由一个空数组变为数组里面有4个元素
  bannerList: {
    handler(newValue, oldValue) {
      // 通过watch监听bannerList属性的属性值的变化
      // 如果执行handler方法,代表组件实例身上这个属性的属性值已经有了 【是一个数组】
      // 当前的这个函数执行,只能保证bannerList数据已经有了,无法保证v-for执行结束
      // v-for执行完毕了,才有结构【现在在watch当中,没办法保证】
      // nextTick: 在下次DOM更新 循环结束之后 执行延迟回调。在 修改数据之后 立即使用这个方法,获取更新后的DOM ,
      // 下次指 数据已经有了 且 v-for已经渲染完毕(指循环结束之后)
      this.$nextTick(() => { // 当执行回调的时候,保证服务器的数据回来了,且 v-for 执行完毕了,所以轮播图的结构一定有了
        var mySwiper = new Swiper('.swiper-container', {
          loop: true, // 循环模式选项
          // 如果需要分页器
          pagination: {
            el: '.swiper-pagination',
            clickable: true // 小点点击可以切换
          },
          // 如果需要前进后退按钮
          navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
          }
        });
      })
    }
  }
}

4. 完整代码

<template>
  <div class="list-container">
    <div class="sortList clearfix">
      <div class="center">
        <!--banner轮播-->
        <div class="swiper-container" id="mySwiper">
          <div class="swiper-wrapper">
            <!-- carousel 指轮播图 -->
            <div class="swiper-slide" v-for="(carousel) in bannerList" :key="carousel.id">
              <img :src="carousel.imgUrl" />
            </div>
          </div>
          <!-- 如果需要分页器 -->
          <div class="swiper-pagination"></div>
          <!-- 如果需要导航按钮 -->
          <div class="swiper-button-prev"></div>
          <div class="swiper-button-next"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
// 引入 Swiper
import Swiper from 'swiper'
// 引入 Swiper 中CSS样式
import 'swiper/css/swiper.css'
import 'swiper/css/swiper.min.css'
export default {
  name: 'ListContainer',
  mounted() { // mounted 组件挂载完毕,正常的结构(DOM)全有了
    // 派发actions 通知Vuex发送Ajax请求,将数据存储在仓库当中
    this.$store.dispatch('getBannerList');
    // 在 new Swiper 之前,页面中的结构必须有,现在把swiper实例放在mounted里面,不能实现功能(因为结构还不完整)
    // 为什么结构还不完整? 如果写在mounted中,在 new Swiper 之前,还未修改仓库中的bannerList数据
    // 因为dispatch当中涉及到异步语句,导致v-for遍历的时候 结构还没有完整 因此不行
    // setTimeout(() => { // 不是最好的
    //   var mySwiper = new Swiper('.swiper-container', {
    //     loop: true, // 循环模式选项
    //     // 如果需要分页器
    //     pagination: {
    //       el: '.swiper-pagination',
    //       clickable: true // 小点点击可以切换
    //     },
    //     // 如果需要前进后退按钮
    //     navigation: {
    //       nextEl: '.swiper-button-next',
    //       prevEl: '.swiper-button-prev',
    //     }
    //   });
    // }, 2000)
  },
  computed: {
    ...mapState({
      bannerList: function (state) {
        return state.home.bannerList;
      }
    })
  },
  watch: {
    // 监听bannerList数据的变化。因为这条数据发生过变化---由一个空数组变为数组里面有4个元素
    bannerList: {
      handler(newValue, oldValue) {
        // 通过watch监听bannerList属性的属性值的变化
        // 如果执行handler方法,代表组件实例身上这个属性的属性值已经有了 【是一个数组】
        // 当前的这个函数执行,只能保证bannerList数据已经有了,无法保证v-for执行结束
        // v-for执行完毕了,才有结构【现在在watch当中,没办法保证】
        // nextTick: 在下次DOM更新 循环结束之后 执行延迟回调。在 修改数据之后 立即使用这个方法,获取更新后的DOM ,
        // 下次指 数据已经有了 且 v-for已经渲染完毕(指循环结束之后)
        this.$nextTick(() => { // 当执行回调的时候,保证服务器的数据回来了,且 v-for 执行完毕了,所以轮播图的结构一定有了
          var mySwiper = new Swiper('.swiper-container', {
            loop: true, // 循环模式选项
            // 如果需要分页器
            pagination: {
              el: '.swiper-pagination',
              clickable: true // 小点点击可以切换
            },
            // 如果需要前进后退按钮
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            }
          });
        })
      }
    }
  }
}
</script>

轮播图的实现思想主要就是:使用mockjs插件模拟数据,并使用store仓库,以及其中的方法获取数据,再使用v-for将数据渲染到页面,最后使用swiper插件 创建swiper实例,实现轮播图的效果(一定要弄清楚,什么时候 创建swiper实例【当页面中已经有了结构】)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值