Vue项目中使用npm i swiper插件踩坑记录

在一个 Vue 项目中使用的,npm 的 swiper 插件,遇到了一些坑,记录一下填坑过程。

首先,npm 安装 Swiper :

npm install swiper --save-dev

引入 Swiper :我是在 main.js 中添加如下代码:

import Swiper from "swiper"
@import "swiper/dist/css/swiper.css";//样式文件

使用 Swiper :

<div class="swiper-container">
    <div class="swiper-wrapper">
        <!-- Slides -->
        <div class="swiper-slide">Slide 1</div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
        ...
    </div>
    <!-- 如果需要分页器 -->
    <div class="swiper-pagination"></div>

    <!-- 如果需要翻页按钮 -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>

    <!-- 如果需要滚动条 -->
    <div class="swiper-scrollbar"></div>
</div>

初始化 Swiper :

var mySwiper = new Swiper(".notice-swiper", {
  direction: 'vertical',//垂直滚动
  speed: 400,//过渡时间
  loop: true,//循环
  autoplay: {
    delay: 5000,//自动滚动|时间
  },
});

遇到的问题:

1、使用静态数据时,一切正常, Swiper 可以正常滚动和滑动。但是使用动态数据时,会出现不能自动滚动/播放甚至数据显示不正常的现象。

解决办法:添加一个 observer 属性。

observer 属性:为 true 时,Swiper 会启用 Mutation Observer 模式,每当元素的样式更改或子元素变动(增加/删除)时都会刷新(重新初始化)Swiper。

var mySwiper = new Swiper(".notice-swiper", {
  direction: 'vertical',//垂直滚动
  speed: 400,//过渡时间
  loop: true,//循环
  observer: true,
  autoplay: {
    delay: 5000,//自动滚动|时间
  },
});

2、使用 v-if 条件让 Swiper 动态显示时,界面混乱,无法切换等问题。

解决办法:添加 observeParents 属性。

observeParents 属性:将 observe 应用于 Swiper 的父元素。当 Swiper 的父元素变化时,例如 window.resize,Swiper 就会更新。

var mySwiper = new Swiper(".notice-swiper", {
  direction: 'vertical',//垂直滚动
  speed: 400,//过渡时间
  loop: true,//循环
  observer: true,
  observeParents: true,
  autoplay: {
    delay: 5000,//自动滚动|时间
  },
});

3、使用 v-for 循环和 v-if 条件控制 Swiper 的数量时, loop 属性不生效,自动播放到最后一个后停止,不能循环播放。

可能的原因: v-for 循环和 v-if 条件渲染还没有完成,Swiper 就被初始化了。这样就会导致 Swiper 错乱,功能异常。 

解决办法:将 Swiper 放在 $nextTick 下一个 UI 帧再初始化。

Vue.nextTick 用于延迟执行一段代码。Vue 的官方文档详细解释:

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0)代替。

例如,当你设置vm.someData = 'new value',该组件不会立即重新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。多数情况我们不需要关心这个过程,但是如果你想在 DOM 状态更新后做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

this.$nextTick(() => { // 下一个UI帧再初始化swiper
  this._initSwiper()
});

如果需要在数据请求结束后执行,可以这样写:

getList().then(res => {
  if (res.data.code == 0) {
    this.$nextTick(() => { // 下一个UI帧再初始化swiper
      this._initSwiper()
    });
  }
})

这样基本可以解决 Swiper 不能自动/循环播放的问题了。

本文主要整理了 swiper不能循环播放,swiper不能自动播放,swiper初始化,npm swiper相关问题,swiper loop不生效,swiper autoplay不生效等问题,希望对你有所帮助。

赞 (0)
分享到: +

评论 沙发

Avatar

换个身份

  • 昵称 (必填)
  • 邮箱 (选填)