微信小程序展示不定长菜单项轮播滑动
👏文末分享源代码。记得点赞+关注+收藏!
1.实现效果
2.实现原理
- swiper组件:
indicator-dots:
面板指示点,可更改原生组件的样式(若有更复杂样式,可自定义指示点),当只有一页数据的时候不展示该指示点,判断数组长度,动态修改值。
autoplay:
是否自动轮播。
bindanimationfinish:
动画结束时会触发 animationfinish 事件,结合e.detail.source,避免抖动效果。 current:
当前所在滑块的 index。(自定义指示点可用于获取指示点所在位置)
- 数组拆分
设置当前轮播图展示几个菜单项,根据当前页展示的菜单项总数为长度,将数组以该长度分为几组数组(方法很多,可自行实现) eg:[1,2,3,4,5,6]==>一页展示3条数据,即拆分为[[1,2,3,],[4,5,6]]
- 不定长菜单项
一般来说,考虑到菜单项的名称较长等因素,一行最多展示5条数据,多于数据换行。 通常在ui设计中,菜单项展示两行情况居多。 基于以上两种情况: 我们通过一个参数来动态的设置每个菜单项的宽度,设置总宽为100%,菜单项宽度=100%/拆分参数
- 拆分参数
let arrLen=一页展示总菜单项(即数组拆分的长度);
let oneLen=拆分参数
用arrLen将数组拆分成某几组数组 eg:现有17个菜单项,按照arrLen=6为一组拆分,可得到数组的长度为3,即表示swiper的轮播页面为3页
设想: 由于一行最多展示5条数据,我们不考虑一页会超出10条,若arrLen>10,设其为10;
arrLen = arrLen > 10 ? 10 : arrLen;
当设置10个一组,分两行,即每行5个,即拆分参数=5 当设置8个一组,分两行,即每行4个,即拆分参数=4 当设置6个一组 ,分两行,即每行3个,即拆分参数=3 ... 按照ui视觉,不考虑奇数项,若arrLen为奇数,设置其为自身+1;
- 设置页面元素宽度
style="width:{{100/oneLen}}%"
- 一些问题
当设置4个一组 ,分两行,即每行2个,即拆分参数=2,此时会发现页面排版很丑陋(当然,一般情况下不会这么设置,不符合审美哈哈) 那么当arrLen大于5时候,oneLen=arrLen/2,反之为arrLen,即不进行分行。
oneLen = arrLen > 5 ? arrLen / 2 : arrLen
那么当arrLen大于5时候,若arrLen为奇数,设置其为自身+1;反之不增。
let isOdd = (arrLen % 2) === 0;
if (!isOdd && arrLen > 5) arrLen = arrLen + 1;`
当arrLen=5时:
当arrLen=4时:
当arrLen=3时:
3.实现代码
<view class="band_box flex-row">
<swiper class="swiper_band {{arrLen<6 && 'swiper_band_small'}}" current="{{swiperCurrent}}" indicator-dots="{{lists.length>1?true:false}}" autoplay="{{false}}" bindanimationfinish="swiperChange">
<swiper-item wx:for="{{lists}}" wx:key="index">
<view class="flex-row flex-wrap">
<block wx:for="{{item}}" wx:key="item" wx:for-item="item0">
<view class="flex-column band_item" style="width:{{100/oneLen}}%">
<image src="{{item0.icon}}" class="band_icon" />
<text>{{item0.name}}</text>
</view>
</block>
</view>
</swiper-item>
</swiper>
</view>
page {
padding : 20px 0;
background: #f7dada;
}
.band_box {
font-size : 26rpx;
color : #575757;
box-sizing: border-box;
padding : 22rpx;
}
.swiper_band {
width : 100%;
height: 330rpx;
}
.swiper_band_small {
width : 100%;
height: 165rpx;
}
.swiper_band .wx-swiper-dots.wx-swiper-dots-horizontal {
margin-bottom: -15rpx;
}
.swiper_band .wx-swiper-dot {
margin-left : -5rpx;
width : 40rpx;
height : 10rpx;
background : rgba(40, 146, 255, .5);
border-radius: 4rpx;
}
.swiper_band .wx-swiper-dot-active {
width : 40rpx;
height : 10rpx;
background : #2892FF;
border-radius: 4rpx;
}
.band_item {
width : 25%;
float : left;
margin-bottom: 19rpx;
}
.band_icon {
width : 87rpx;
height : 87rpx;
margin-bottom: 11rpx;
border-radius: 50%;
}
const app = getApp()
const listMenu = [
{
name: '菜单1',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单2',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单3',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单4',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单5',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单6',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单7',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单8',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单9',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单10',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单11',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单12',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单13',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单14',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单15',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单16',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
{
name: '菜单17',
icon: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg'
},
];
Page({
data: {
swiperCurrent: 0,//当前所在滑块的 index
lists: [],
arrLen: 3,//分组数 最大值10,当为奇数时候,默认加1提示为偶数
oneLen: 0,//一行展示多少
},
onShow() {
this.getData()
},
/**
* 获取菜单
* @param {*} e
*/
getData() {
let dataList = listMenu,
{ arrLen, oneLen } = this.data, lists = [],
isOdd = (arrLen % 2) === 0;
if (!isOdd && arrLen > 5) arrLen = arrLen + 1;
arrLen = arrLen > 10 ? 10 : arrLen;
oneLen = arrLen > 5 ? arrLen / 2 : arrLen;
for (var i = 0; i < dataList.length; i += arrLen) {
lists.push(dataList.slice(i, i + arrLen));
}
this.setData({
lists, arrLen,
oneLen,
})
},
/**
* 轮播图切换
* @param {*} e
*/
swiperChange: function (e) {
if (e.detail.source == "touch" || e.detail.source == "autoplay") {
this.setData({
swiperCurrent: e.detail.current
})
}
},
})
4.写在最后
看完本文如果觉得有用,记得点赞+关注+收藏鸭
更多小程序相关,关注💯苏苏的bug,💢苏苏的github,😎苏苏的码云~
转载自:https://juejin.cn/post/7157720418705473573