使用Swiper做一个周日历功能,要求滑动swiper时,可以显示上一周/下一周的日期。
一开始设想的是使用二维数组存放3个周的日期,右滑时push接下来的周,然后shift第一项,左滑反之,试了几种方法,要么是日期不见了,要么就是判断左滑右滑失败了。
看到这篇文章《小程序 - swiper滑动日历》,受到了启发,于是继续尝试,这次总算是成功了。
第二天根据这个思路又写了一个按月查看的日历,相比这个稍微简单一些
=>小程序Swiper日历二
使用数组存放3个周的日期,weeks = [[],[],[]]
Swiper设置为循环播放 circular="true"
(这是关键之一)
初次渲染使用weeks [0], index=0
假设:weeks = [[week2], [week3],[week1]]
,其中week2是初始化时显示的,此时index:0,
为什么weeks[2]是week1呢?因为swiper是循环的,那我们左滑时,week2的左边应该是week1,也就是放在weeks[2]的位置。所以一定从循环的角度来为数组赋值。
接下来判断方向(左滑/右滑)
根据方向,写出当swiper的current值为0,1,2时的具体处理代码,修改weeks 和index的值
第一次右滑后,index:1
,显示week3,weeks = [[week2],[week3],[week4]]
第二次右滑后,index:2
,显示week4,weeks = [[week5],[week3],[week4]]
第三次右滑后,index:0
,显示week5,weeks = [[week5],[week6],[week4]]
左滑如是推出。
<!-- wxml -->
<swiper class="swiper" current="{{index}}" circular="true" bindchange="change">
<swiper-item class="swipe-days" wx:for="{{weeks}}" item-id="item{{index}}">
<view class="day {{d.date==currentDate ? 'selected':''}}" wx:for="{{item}}" wx:for-item="d" data-date="{{d.date}}" bindtap="tapDate">
{{d.day}}</view>
</swiper-item>
</swiper>
// JS
// 使用了dayjs日期库,方便直观
// 这里删除了我自己的一些取数据的代码,如果只需要做日历,应该还可以再优化一下。
const dayjs = require("./dayjs");
const db = wx.cloud.database();
const _ = db.command;
Page({
/**
* 页面的初始数据
*/
data: {
index: 0,
weeks: [],
currentDate: dayjs().format("YYYY-MM-DD"),
today: dayjs().format("YYYY-MM-DD"),
startDate: null,
endDate: null,
weekName: [
{ name: '日', cls: 'weekend' },
{ name: '一', cls: '' },
{ name: '二', cls: '' },
{ name: '三', cls: '' },
{ name: '四', cls: '' },
{ name: '五', cls: '' },
{ name: '六', cls: 'weekend' }
]
},
onLoad: function(options) {
this.init();
},
change(e) {
let { currentDate, index, weeks, startDate, endDate } = this.data
let current = e.detail.current
let aDate = current - index == -2 || current - index == 1 ? endDate : startDate
if (current == 0) {
weeks = [this.getWeek(0, aDate), this.getWeek(1, aDate), this.getWeek(-1, aDate)]
startDate = weeks[2][0].date,
endDate = weeks[1][6].date,
currentDate = weeks[0][0].date
}
if (current == 1) {
weeks = [this.getWeek(-1, aDate), this.getWeek(0, aDate), this.getWeek(1, aDate)]
startDate = weeks[0][0].date,
endDate = weeks[2][6].date,
currentDate = weeks[1][0].date
}
if (current == 2) {
weeks = [this.getWeek(1, aDate), this.getWeek(-1, aDate), this.getWeek(0, aDate)]
startDate = weeks[1][0].date,
endDate = weeks[0][6].date,
currentDate = weeks[2][0].date
}
this.setData({
weeks, startDate, endDate, currentDate, index: current
})
},
tapDate(e) {
let date = e.currentTarget.dataset.date
this.setData({
currentDate: date
})
},
init() {
// 构造一个数组[[],[],[]],里边放3个星期的数据,[0]放本周,[1]放下一周,[2]放上一周
let { weeks, startDate, endDate, currentDate } = this.data
weeks = [this.getWeek(0, currentDate), this.getWeek(1, currentDate), this.getWeek(-1, currentDate)]
startDate = weeks[2][0].date,
endDate = weeks[1][6].date
this.setData({
weeks, startDate, endDate
})
},
// direction 接收 0,1,-1三个值,分别代表,本周,下周,上周
getWeek(direction, date) {
date = dayjs(date)
let firstDayOfWeek = date.subtract(date.day(), "day");
let arr = []
for (let i = direction * 7; i < (1 + direction) * 7; i++) {
let d = firstDayOfWeek.add(i, "day")
arr.push({
date: d.format("YYYY-MM-DD"),
day: d.format("DD"),
})
}
return arr;
},
});
.swiper { height: 80rpx; margin-bottom:16rpx;}
.swipe-days{ display: flex; justify-content: space-around; }
.day { display: inline-flex;height: 80rpx; width: 80rpx; border-radius: 80rpx; justify-content: center; line-height: 80rpx;font-size:24rpx;}
.selected {background-image: linear-gradient(-45deg, #3857e3, #567bfd);color: #fff;font-weight: bold }