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

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

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

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

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

<swiper
   class="bannerSwiper"
   style="height: {{swiperHeight}}px"
 >
   <block wx:for="{{partData}}" wx:key="key">
     <swiper-item>
       <view class="imgWrapBanner">
         <image
           class="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) return
      const that = this
      const 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。

<swiper
  class="bannerSwiper"
  current="{{currentIndex}}"
>
  <block wx:for="{{partData}}" wx:key="key">
    <swiper-item>
      <view class="imgWrapBanner">
        <image
          class="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为0
      this.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">
        <image
          class="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。

<swiper
  autoplay
  interval="{{5000}}"
  circular
  class="bannerSwiper"
  current="{{current}}"
  bindchange="handleCarouselChange"
>
  <block wx:for="{{partData}}" wx:key="key">
    <swiper-item>
      <view
        class="imgWrapBanner {{carouselIndex === index ? 'active': ''"
      >
        <image
          class="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
      })
    }
  }
})
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐