最近用 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 来进行说明。
实践
安装依赖
首先是项目安装依赖:
1 2 3 4 5
| npm i vue-awesome-swiper@4.1.1 npm i swiper@6.8.4
npm i swiper@5.4.5
|
这一步不难,不过如果你用 npm
的话,可能会安装失败,可以尝试增加参数:
1
| npm i swiper@6.8.4 --legacy-peer-deps
|
模版代码
模版部分参考代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <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> <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>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <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 导包部分
这部分稍微有点复杂:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/css/swiper.min.css'
import SwiperClass, { Autoplay, Pagination } from 'swiper'
import 'swiper/swiper.min.css' import 'swiper/swiper-bundle.min.css'
SwiperClass.use([Autoplay, Pagination])
|
项目这里用的是 vue-awesome-swiper
4.1.1 版本,需要配合 swiper
6.8.4 或者 5.4.5 来使用。
不同的 Swiper 版本,代码已有清晰的注释了。
根据你的 Swiper 版本来决定写法,选择其一即可。
要注意的是,你可能看到有人把插件在 js 配置里启动,而不是使用 use
,我自己测试是不行的。
1 2 3 4
| const swiperOption = { modules: [Autoplay, Pagination] }
|
vue 逻辑部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| export default { components: { Swiper, SwiperSlide }, data () { return { 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) { 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 个:
1 2 3 4
| export enum ComponentEvents { Ready = 'ready', ClickSlide = 'clickSlide', }
|
以及透传 swiper
事件若干:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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,自行查阅即可。
–END–