Vue2 使用 vue-awesome-swiper swiper
最近用 Vant@2 中的 Swipe
时候,发现 iPhone 手机轮播动画可能丢失。但是有的项目升级 Vant@2 的小版本后,解决了。也有的项目,用最新版也不能解决。同时发现它的计算宽度有时候在 iPhone 下还有问题。这也使得必须考虑切换为标准版 swiper
了。
说明
Vue@2 项目,可以直接使用 swiper
的 js 版本,不过接入起来比较麻烦,尤其是控制各种事件,很少有人这么做了。
最常见就是使用 vue-awesome-swiper
。目前主要是用 4.1.1 版本,也有人用 3.1.3 版本。最新的 5.0.1 应该是为了兼容比较新版本的 Swiper,且不会继续维护了,使用人数也非常少。
其中:
- 4.1.1 要配合
swiper
的 5/6 版本来用。 - 3.1.3 要配合
swiper
的 4 版本来用。
下文以 vue-awesome-swiper
4.1.1 来进行说明。
实践
安装依赖
首先是项目安装依赖:
npm i vue-awesome-swiper@4.1.1
npm i swiper@6.8.4
# 或者安装 Swiper@5 系列版本,但代码略有不同,下文会说明
npm i swiper@5.4.5
这一步不难,不过如果你用 npm
的话,可能会安装失败,可以尝试增加参数:
npm i swiper@6.8.4 --legacy-peer-deps
模版代码
模版部分参考代码如下:
<template>
<div class="container">
<Swiper
:options="swiperOption"
ref="mySwiper"
@clickSlide="onSlideClick"
@slideChange="onSlideChange">
<SwiperSlide v-for="item in list" :key="item.id">
<div class="item" :style="{backgroundColor:item.bg}">
{{ item.text }}
</div>
</SwiperSlide>
<!-- swiper 自带指示器 -->
<template #pagination>
<div class="swiper-pagination"/>
</template>
</Swiper>
<!-- 自定义指示器 -->
<div class="pagination">
<span
v-for="idx in list.length"
:key="idx"
:class="{cur:(idx-1)===curIndex}"/>
</div>
</div>
</template>
<style lang="less" scoped>
.container {
.item {
height: 100px;
}
/* 简易的指示器效果 */
.pagination {
display: flex;
span {
margin: 0 2px;
width: 10px;
height: 10px;
background-color: grey;
&.cur {
background-color: red;
}
}
}
}
</style>
指示器,可以使用自带的,也可以自己写一个完全定义的。看你的需求来定。
这部分没什么可说的。具体的调用方法,下文部分会提到。
vue 导包部分
这部分稍微有点复杂:
import {Swiper, SwiperSlide} from 'vue-awesome-swiper'
// ==== swiper@5.4.5 写法 ====
// 导入 CSS
import 'swiper/css/swiper.min.css'
// ==== swiper@5.4.5 写法 END ====
// ==== swiper@6.8.4 写法 ====
// 如果需要额外插件,则要单独导入对应模块,并进行加载后才可以使用
import SwiperClass, {Autoplay, Pagination} from 'swiper'
// 导入 CSS
// 如果功能简单,只是简单轮播不用插件的,可以使用 swiper.min.css
// 否则建议直接使用 swiper-bundle.min.css
import 'swiper/swiper.min.css'
import 'swiper/swiper-bundle.min.css'
// Swiper 加载插件
SwiperClass.use([Autoplay, Pagination])
// ==== swiper@6.8.4 写法 END ====
项目这里用的是 vue-awesome-swiper
4.1.1 版本,需要配合 swiper
6.8.4 或者 5.4.5 来使用。
不同的 Swiper 版本,代码已有清晰的注释了。
根据你的 Swiper 版本来决定写法,选择其一即可。
要注意的是,你可能看到有人把插件在 js 配置里启动,而不是使用 use
,我自己测试是不行的。
const swiperOption = {
modules: [Autoplay, Pagination] // 这样写不行
// ...
}
vue 逻辑部分
export default {
components: {Swiper, SwiperSlide},
data() {
return {
// Swiper 的参数
swiperOption: {
// 如果使用自带指示器,要增加这个
pagination: {el: '.swiper-pagination'},
// 是否循环播放
loop: true,
// 自动轮播控制
autoplay: {
delay: 1000,
stopOnLastSlide: false,
disableOnInteraction: false
}
},
// 当前轮播索引
curIndex: 0,
// 测试数据
list: [
{id: 1, text: 'A', bg: '#f00'},
{id: 2, text: 'B', bg: '#0f0'},
{id: 3, text: 'C', bg: '#00f'}
]
}
},
methods: {
// 点击每个轮播区域触发
onSlideClick(index, reallyIndex) {
// 需要使用 reallyIndex,这个是真实的轮播索引
console.log('当前的index', reallyIndex)
},
// 当轮播滑动改变时触发(人工滑动、自动轮播都会触发)
onSlideChange() {
const curIndex = this.$refs.mySwiper.$swiper.realIndex
this.curIndex = curIndex
}
}
}
有几点要注意的是:
- 配置参数时,由于可配置参数太多了,所以注意查阅文档,不要网上乱抄。
swiper
4 之前版本,有些写法差异,需要单独查阅下。不过咱们用不到这些老版本了。swiper
4~9(最新的就是9),API 基本上没差别,可以通用。英文官方文档见此,国内中文版见此。 - 尤其是
autoplay
,现在都是对象形式,不要用老的autoplay: true
,会有问题。比如开启自动轮播,一旦人工触摸后,就不能自动轮播了(disableOnInteraction
失效)。 @clickSlide
事件,必须用第二个参数reallyIndex
。因为轮播要做收尾相接,故 Swiper 会帮你补充元素的。比如轮播 3 个,实际是有 5 个节点的。reallyIndex
可以得到0~2
,而index
是0~4
。@slideChange
事件,收到自动轮播和手动控制影响,可能同一条数据触发两次。故这里只建议保存当前索引号,不推荐做别的任务。
支持的事件
可以用的事件,可以参考 vue-awesome-swiper
4.1.1 源码的这里:
vue-awesome-swiper
定义的事件有 2 个:
export enum ComponentEvents {
Ready = 'ready',
ClickSlide = 'clickSlide',
}
以及透传 swiper
事件若干:
export const SWIPER_EVENTS: CommonEvent[] = [
'init',
'beforeDestroy',
'slideChange',
'slideChangeTransitionStart',
'slideChangeTransitionEnd',
'slideNextTransitionStart',
'slideNextTransitionEnd',
'slidePrevTransitionStart',
'slidePrevTransitionEnd',
'transitionStart',
'transitionEnd',
'touchStart',
'touchMove',
'touchMoveOpposite',
'sliderMove',
'touchEnd',
'click',
'tap',
'doubleTap',
'imagesReady',
'progress',
'reachBeginning',
'reachEnd',
'fromEdge',
'setTranslate',
'setTransition',
'resize',
'observerUpdate' as CommonEvent,
'beforeLoopFix' as CommonEvent,
'loopFix' as CommonEvent
]
具体的事件用途,参考上文提到的英文官方文档 - events,自行查阅即可。