月份卡片无限滚动和预加载示例,只要 list 长度=3,swiper 的 circular 就能做出无限滑动的错觉;再配合月份数组的整体左移/右移,让视觉与数据始终保持同步
swiper 注意开启循环 circular,默认停在中间卡片 current="{{1}}"
右滑实现原理,左滑同样的,通过判断swiper下标调整list位置即可
<swiper class="swiper" circular indicator-dots current="{{1}}" bindanimationfinish="onSwiperFinish">
<swiper-item wx:for="{{list}}" wx:key="id">
<view class="page" style="background: {{item.color}}">
<view class="txt">{{item.title}}</view>
<view class="txt">当前月 - {{timelist[swiper_index]}}</view>
</view>
</swiper-item>
</swiper>
Page({
data: {
list: [{
id: 1,
title: '页面 1',
color: '#ff7675'
},
{
id: 2,
title: '页面 2',
color: '#74b9ff'
},
{
id: 3,
title: '页面 3',
color: '#55efc4'
}
],
swiper_index: 1, //当前滑动下标
swiper_diff: 0, //滑动操作,1右滑,0左滑
last_swiper_index: 1, //上一个滑动下标
timelist: []
},
async onLoad() {
this.IniDate();
},
// 初始化日期数据
async IniDate(date = new Date()) {
console.log("开始初始化时间...");
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const currentDate = `${year}/${month}/${day}`;
this.setData({
now_date: currentDate,
now_date_: `${year}-${month}-${day}`,
now_Year: year,
now_Month: month,
});
console.log("时间初始化完成~");
const timeArr = this.data.now_date.split('/');
const currentMonth = timeArr[1].padStart(2, '0');
const currentYear = timeArr[0];
let searchMonthList = [`${currentYear}-${currentMonth}`];
// 计算前后月份
if (Number(currentMonth) > 1 && Number(currentMonth) < 12) {
const preMonth = (Number(currentMonth) - 1).toString().padStart(2, '0');
const nextMonth = (Number(currentMonth) + 1).toString().padStart(2, '0');
searchMonthList = [`${currentYear}-${preMonth}`, searchMonthList[0], `${currentYear}-${nextMonth}`];
} else if (Number(currentMonth) === 1) {
const preYear = Number(currentYear) - 1;
searchMonthList = [`${preYear}-12`, searchMonthList[0], `${currentYear}-02`];
} else if (Number(currentMonth) === 12) {
const nextYear = Number(currentYear) + 1;
searchMonthList = [`${currentYear}-11`, searchMonthList[0], `${nextYear}-01`];
}
// 处理日历列表展示顺序
const index = this.data.swiper_index;
const diff = this.data.swiper_diff;
let allList = [];
const list = searchMonthList;
// 右滑处理
if (diff == 1) {
if (index === 0) {
allList = [list[1], list[2], list[0]];
} else if (index === 1) {
allList = [list[0], list[1], list[2]];
} else if (index === 2) {
allList = [list[2], list[0], list[1]];
}
} else {
// 左滑处理
if (index === 1) {
allList = [list[0], list[1], list[2]];
} else if (index === 0) {
allList = [list[1], list[2], list[0]];
} else if (index === 2) {
allList = [list[2], list[0], list[1]];
}
}
console.log(diff, index, allList)
this.setData({
timelist: allList
});
},
// 用户滑动swiper
onSwiperFinish(e) {
const swiper_index = e.detail.current;
const last_swiper_index = this.data.last_swiper_index
const diff = swiper_index - last_swiper_index;
// 判断滑动方向 1,-2 右滑, -1,2 左滑
if (diff === 1 || diff === -2) {
this.setData({
swiper_diff: 1
})
console.log("右滑");
this.nextMonth();
} else if (diff === -1 || diff === 2) {
this.setData({
swiper_diff: 0
})
console.log("左滑");
this.prevMonth();
}
this.setData({
swiper_index: swiper_index,
last_swiper_index: swiper_index
})
},
// 切换到上个月
async prevMonth() {
const date = new Date(this.data.now_date);
const prev = await this.prevMonth_date(date);
console.log(prev)
this.IniDate(prev, true);
},
// 切换到下个月
async nextMonth() {
const date = new Date(this.data.now_date);
const next = await this.nextMonth_date(date);
console.log(next)
this.IniDate(next, true);
},
nextMonth_date(date) {
const d = new Date(date); // 克隆
const dayOfMonth = d.getDate();
d.setDate(1); // 先挪到 1 号,避免 31→3 月 3 日
d.setMonth(d.getMonth() + 1);
const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
d.setDate(Math.min(dayOfMonth, lastDay)); // 取较小值防止溢出
return d;
},
prevMonth_date(date) {
const d = new Date(date); // 克隆
const dayOfMonth = d.getDate();
d.setDate(1); // 先挪到 1 号,避免 31→3 月 3 日
d.setMonth(d.getMonth() - 1);
const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
d.setDate(Math.min(dayOfMonth, lastDay)); // 取较小值防止溢出
return d;
},
});
/* pages/index/index.wxss */
.wrap {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.swiper {
margin-top: 200rpx;
width: 90%;
height: 500rpx;
margin-left: 5%;
border-radius: 10rpx;
}
.page {
border-radius: 10rpx;
padding: 10rpx;
height: 500rpx;
font-size: 40rpx;
}
.txt {
margin-top: 100rpx;
text-align: center;
color: #fff;
font-size: 40rpx;
width: 100%;
height: 100rpx;
}
评论 (0)