微信小程序swiper组件常见问题及解决方法

传送门:小程序swiper组件官方文档

整理微信小程序swiper组件使用中遇到的一些问题及其解决方法:

1、swiper轮播图图片高度自适应

  • 描述:
    swiper组件有个默认高度150px,有时候做轮播图特效时要求图片高度能自适应,而不是写死的宽高。

  • 解决方法:
    首先给image标签设置mode=“widthFix”,然后绑定bindload事件,然后在事件方法里通过e.detail.width和e.detail.height获取图片宽高,获取swiper容器元素的宽度,计算出自适应后图片的高度,将此高度通过style属性设置给swiper容器。
    这样做后,最终自适应的高度大小取决于最后一张加载完的图片的高度(不一定是数据数组最后一张,而是最后加载完的那张),一般来说后台配置的轮播图图片高度都会保持一致,所以是能满足实际需求的。

<swiperclass="bannerSwiper"style="height: {{swiperHeight}}px"><block wx:for="{{partData}}" wx:key="key"><swiper-item><view class="imgWrapBanner"><imageclass="imgBanner"src="{{item.pic}}"mode="widthFix"bindload="onImageLoad"></image></view></swiper-item></block></swiper>
Component({properties: {partData: {type: Array,value: []}},data: {swiperHeight: 100},methods: {onImageLoad (e) {if (!e.detail) returnconst that = thisconst query = wx.createSelectorQuery().in(this)query.select('.bannerSwiper').boundingClientRect(rect => {that.setData({swiperHeight: rect.width / e.detail.width * e.detail.height})}).exec()}}
})
.bannerSwiper {width: 100%;overflow: hidden;
}
.imgWrapBanner {width: 100%;.imgBanner {display: block;width: 100%;}
}

2、刷新页面数据后swiper出现空白

  • 描述:
    常见于轮播图中,有时刷新数据出现某张轮播图空白,查看控制台日志,出现警告信息: [swiper] current无效,请修改current值。

  • 解决方法:
    原因是当轮播图滚动到某个比较大的index值时,此时刷新页面,恰好轮播图后台配置里下架了几张,导致此时的index值溢出了新数据下轮播图数组的下标,组件展示也就乱了。知道了原因那就好解决了,需要先给swiper组件绑定个属性current,在刷新接口数据后对比轮播图数组前后长度的变化,长度不一致就重置current值为0。

<swiperclass="bannerSwiper"current="{{currentIndex}}"
><block wx:for="{{partData}}" wx:key="key"><swiper-item><view class="imgWrapBanner"><imageclass="imgBanner"src="{{item.pic}}"></image></view></swiper-item></block>
</swiper>
Component({properties: {partData: {type: Array,value: []}},data: {currentIndex: 0},observers: {partData () {// 防止出现 [swiper] current无效,请修改current值 的警告,会导致图片空白// 我这里是通过Component的observers功能监听数据变化后就直接重置currentIndex// 解决思路是一样的,最好就是获取到接口数据后判断数据数组前后长度不一致再重置currentIndex为0this.setData({currentIndex: 0})}}
})

3、swiper边框圆角在个别机型上没有效果

  • 描述:
    swiper边框圆角一般设置border-radius就行,但是有天发现在一个苹果机上没有效果,边框还是直的。。。

  • 解决方法:
    添加属性 transform: translateY(0); 黑科技?不懂,只能吐槽下小程序官方!

<swiper class="bannerSwiper"><block wx:for="{{partData}}" wx:key="key"><swiper-item><view class="imgWrapBanner"><imageclass="imgBanner"src="{{item.pic}}"></image></view></swiper-item></block>
</swiper>
.bannerSwiper {width: 100%;border-radius: 16rpx;overflow: hidden;transform: translateY(0);
}

4、swiper轮播卡死、不停晃动的问题

  • 描述:
    就是轮播时偶尔会出现卡死的情况,一直左右晃动,也无法手动滑动切换,小程序自身也处于非常卡顿的状态,说实话我还不知道如何复现,只是感觉在页面切换及息屏亮屏时就容易突然出现。

  • 解决方法:
    估计卡死的时候swiper内部组件出现了死循环,此时swiper绑定的bindchange方法也不会触发,猜测出现该问题的原因是给swiper组件绑定了current属性,然后又在绑定的bindchange事件里改变了current属性值,引起了swiper内部的bug。
    其实在bingchange绑定的事件里打印current绑定的值会发现这个值一直是0不会改变,既然swiper内部没有将它与轮播图当前索引进行同步,那我们也不要改动它的值。
    当然你也可以选择不绑定current值,但本文的第2条里提到了一个bug的出现,需要绑定current值才能避免。
    这样思路就清晰了,我们给current绑定的值和获取索引使用的值用不同的字段来表示,例如给swiper绑定的current属性,这个属性值存储在变量a里,a只用来控制改变swiper轮播位置;给swiper绑定的bindchange事件里,通过e.detail.current获取到值存储在另一个变量b里,b只用来获取当前轮播索引;需要重置数据时,将a和b一起重置为0。

<swiperautoplayinterval="{{5000}}"circularclass="bannerSwiper"current="{{current}}"bindchange="handleCarouselChange"
><block wx:for="{{partData}}" wx:key="key"><swiper-item><viewclass="imgWrapBanner {{carouselIndex === index ? 'active': ''"><imageclass="imgBanner"src="{{item.pic}}"></image></view></swiper-item></block>
</swiper>
Component({properties: {partData: {type: Array,value: []}},data: {current: 0, // 只用于控制轮播位置carouselIndex: 0 // 只用于获取轮播索引},observers: {partData () {// 防止出现 [swiper] current无效,请修改current值 的警告,会导致图片空白this.setData({current: 0,carouselIndex: 0})}},methods: {handleCarouselChange (e) {this.setData({carouselIndex: e.detail.current})}}
})