一、实现轮播图效果
通过请求后台数据获取到轮播图后,我们可使用小程序swiper组件去实现展示轮播图效果:
<!-- 轮播图 -->
<swiper class="swiper" indicator-dots autoplay circular>
<block wx:for="{{ banners }}" wx:key="bannerId">
<swiper-item class="swiper-item">
<image class="image" src="https://juejin.cn/post/{{ item.pic }}" mode="widthFix"></image>
</swiper-item>
</block>
</swiper>
复制代码
需要注意的是,在小程序中,如果不给image组件设置宽高,则image组件的宽高默认为:320px * 240px,为了使image组件的图片与轮播图容器swiper宽度保持一致,则需要进行以下设置:
- 将swiper-item中的image宽度设置为swiper宽度:
.swiper-item .image {
width: 100%;
}
复制代码
因为在小程序中,swiper容器的宽度默认为手机屏幕宽度,所以不需要为swiper容器设置宽度,只需要为image设置宽度即可
- 保持图片宽高比正常,为image设置mode属性,并将mode属性值设置为”widthFix”
代码中包含的swiper相关配置:
- swiper中只能包含swiper-item
- indicator-dots(boolean):是否展示指示圆点
- autoplay(boolean):是否自动播放
- circular(boolean):是否无限循环
具体使用方式及更多功能说明可查看微信官方文档->小程序->组件->视图容器->swiper
二、处理轮播图细节问题(如何动态设置轮播图高度)
在小程序原生swiper组件中,swiper组件的宽度是手机屏幕的宽度,而高度默认固定为150px
而我们将轮播图的宽度设置为swiper容器宽度解决了图片宽度与swiper容器不一致问题,再根据mode=”widthFix”虽解决了图片宽高比的问题,但这样会产生另一个问题:
由于我们的轮播图图片高度是根据设置的mode=”widthFix”计算而来的,而每个机型的屏幕宽度是不一样的,所以此时轮播图通过widthFix计算而来的高度就不一样,此时就会产生以下问题:
比如iphone6/7/8机型上展示的效果如图:
而,iphone5机型展示的效果如图:
可见,由于iphone5机型屏幕宽度窄,所以轮播图高度通过widthFix计算而来的就会变小,轮播图的指示点就会在轮播图下部(因为swiper固定高度为150px,而轮播图此时的高度小于150px)
而我们希望达到的效果为:swiper高度要与轮播图计算而来的高度保持一致。
而图片高度是通过widthFix动态计算而来的,不同机型会不一样,那么我们如何动态获取轮播图高度来设置到swiper上呢?
所以,接下来我们需要进行如下操作来解决此问题:
- 动态获取图片高度
- 将swiper高度设置为图片高度
2-1、动态获取图片高度
轮播图的图片来源于请求的接口,是属于网络图片,而我们只是将image的src设置为请求的图片地址,在此过程中是获取不到图片高度的。所以我们只有确定网络图片下载下来并加载完成了才能获取到图片高度。
那么我们如何才能知道图片加载完成了呢?
通过查看官方文档可发现,小程序为image组件提供了bindload事件,此事件会在图片载入完毕时触发。
但是,我们通过bindload中拿到的图片高度为原始图片的高度,而不是显示到轮播组件上的高度(轮播组件上图片的宽高我们是通过为image设置宽度为100%,mode=”widthFix”计算而来的),所以实际上我们真正要拿到的是image组件的宽高。
2-1-1、获取image组件的宽高
那么如何获取组件的宽高呢?
小程序为我们提供了一个API:wx.createSelectorQuery()
- 首先为image组件绑定bindload事件:
- 在事件中通过API动态获取image组件的高度:
handleSwiperLoaded: function() {
const query = wx.createSelectorQuery()
query.select('.swiper-image').boundingClientRect()
query.exec((res) => {
const rect = res[0]
this.setData({ swiperHeight: rect.height })
})
},
复制代码
2-2、将swiper高度设置为图片高度
由于在小程序中无法动态为wxss中的样式设置值,我们可以将样式写为行内样式,通过改变行内样式来达到效果。
2-3、利用节流函数进行优化
由于轮播图存在多张图片,每张图片加载完成后都会触发一次bindload绑定的函数,实际上只需要获取一遍image组件高度即可,所以可考虑利用lodash提供的节流函数进行优化。