1. 背景
最终要实现的效果如上图所示,一个通知消息卡片的轮播效果。
如果是H5这其实也就是个普普通通的轮播效果,但在小程序里遇到的坑着实不少,这里记录一下填坑过程。
2. 填坑过程
1. 先把基础结构搞出来
<template>
<swiper
:current="currentIndex"
class="swiper-wrapper"
easing-function="easeOutCubic"
:circular="true"
@change="onChange">
<swiper-item v-for="(item, i) in list" :key="i" class="swiper-item">
<view :class="['message-card', { 'active': currentIndex === i }]">
{{ item }}
</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
data() {
currentIndex: 0, // 当前轮播索引
list: [1, 2] // 随便先搞个数据先
},
methods: {
// 轮播切换时获取索引值
onChange(e) {
this.currentIndex = e.detail.current
}
}
}
</script>
<style lang="scss" scoped>
.swiper-wrapper {
display: flex;
align-items: center;
height: 250rpx;
}
.swiper-item {
display: flex;
align-items: center;
}
.message-card {
background-color: #F6F6F6;
width: 188rpx;
height: 127rpx;
border-radius: 8px 0 0 8px;
padding: 0 20rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
&.active {
width: 100%;
height: 175rpx;
margin-left: 28rpx;
margin-right: 20rpx;
padding: 0 24rpx;
border-radius: 8px;
}
}
</style>
查看微信文档得知 swiper 的 display-multiple-items 默认值为1,所以上面的大消息卡片是占满一屏的,还没达到我们预期的一屏显示两个一大一小的消息卡片。
2. 设置display-multiple-items
<swiper :display-multiple-items="2"></swiper>
嗯。。。。。虽然是一屏显示两个一大一小的消息卡片了,但很明显不符合设计稿的要求。
设置 display-multiple-items 为2意味着 swiper-item 各占50%。
那我能不能设置非整数呢?比如 1.3 ,那样 swiper-item 占 100 / 1.3 = 77% ,与设计稿接近,设置完到开发工具看效果。
<swiper :display-multiple-items="1.3"></swiper>
还真可以,不错不错,效果喜人,有内味了!!!!!
3. 出现滑动异常
当我满心欢喜的准备滑动轮播的时候,出现了上面的情况,滑动时右边的swiper-item时而消失时而现身,唉,就是玩儿,跟玩捉迷藏似的。。。。
难道是 display-multiple-items为 1.3 导致的?于是我将其设置为2,这下好,倒是没有出现空白的情况了,但它不能滑动了。。。。哭!
上微信社区看看,果然,这个swiper控件问题还真是挺多,深受其害的人还不少。
4. 解决
这里发现当 list 长度为大于2时,轮播是正常的,list 长度为1的情况下,需求是使卡片占满一屏,所以只需要在 list 长度为1时设置 display-multiple-items 为1即可。
也就是说只需要考虑 list.length === 2时上面出现的异常情况。
但从社区里的反馈来看,指望微信马上修复是没什么希望了,只能自力更生了。
上面说到当list长度大于2时是正常的,嘿嘿嘿。。。画重点:
[1, 2] => [1, 2, 1, 2]
没错,把原本长度为2的 list 将其复制一份,变成 长度为4的 list,这样轮播的时候就像是在1和2之间循环轮播,完美对应需求。
data() {
return {
list: []
}
},
onLoad() {
const arr = [1, 2] // 从接口获取的数据
if (arr.length === 2) {
this.list = [...arr, ...arr]
} else {
this.list = arr
}
}
验证长度超过2时也正常,arr = [1, 2, 3]
// list.length === 1 时设置 display-multiple-items 为1
<swiper
v-if="list.length"
:display-multiple-items="list.length === 1 ? 1 : 1.3"
></swiper>
这里也有一个小坑,动态设置 display-multiple-items 后,如果没有 swiper 没有加v-if="list.length",整个 swiper 会出现空白不显示的情况。
3. 最后
以上就是本文的全部,不说了,我去真机测试了。
如果本文对你有什么帮助,欢迎给个赞!!!