首先我们来看一下最终的效果图:
下面我们来介绍实现思路:
首先,我们要获取的无非就是每一个格子里面的数据。
先获取月,然后点击月切换到另一个月,到了边界线的时候到了上/下年即可。
那么,怎么获取月的数据呢,可以看到月第一天都是1开始,然后xx天,比如1月31天,我们把它枚举出来。
但是月份受到年份影响,所以计算是否闰年就完成了。
上代码
获取这个月的7*5列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | let getMothList = (year, month) => {
var star = new Date(Date.UTC(year, month - 1, 1)).getDay()
let mn = getMothNum(year)[month - 1]
var res = []
var row = []
new Array(35)
.fill('')
.map((_, i) => i - star + 1)
.map(e =>
(e > 0 && e <= mn)
? ({
date: `${year}/${month}/${e}`,
number: e
})
: (null)
)
.forEach((item, i) => {
row.push(jsON.parse(JSON.stringify(item)))
if((i + 1) % 7 == 0){
res.push(row)
row = []
}
})
return res
}
|
然后获取月
1 2 3 4 5 6 | var getMaxY = y => Boolean(
y % 4 ==0 && y % 100 != 0 || y % 400==0
)
var getAugNum = n => getMaxY(n) ? 29 : 28
// --获取年对应的月份
var getMothNum = y => ([ 31, getAugNum(y), 31, 30, 31, 30, 31,31, 30, 31, 30, 31 ])
|
我上面js就这些了(还差上下月切换的没说哈)
但是少了中文的月份,有需要的这个可以再匹配
1 | var mothZh = ['一','二','三','四','五','六','七','八','九','十','十一','十二'].map(e => e + '月')
|
然后就是上下月月份了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | up(e){
var data = e.currentTarget.dataset
if(data.data == '上'){
if(this.data.dateM > 1){
var dateM = this.data.dateM
var dateY = this.data.dateY
this.setDate(dateY, dateM - 1)
}else{
var dateY = this.data.dateY
this.setDate(dateY - 1, 12)
}
}
},
down(e){
var data = e.currentTarget.dataset
if(data.data == '下'){
if(this.data.dateM < 12){
var dateM = this.data.dateM
var dateY = this.data.dateY
this.setDate(dateY, dateM + 1)
}else{
var dateY = this.data.dateY
this.setDate(dateY + 1, 1)
}
}
},
|
上下月操作好了就是更新数据了,更新数据的时候,因为小程序不能在view里面写逻辑,所以我们在mpa里面操作(这是我的业务逻辑,你们不用管他,我之所以放出来是方便大家查看)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | setDate(dateY, dateM){
var date_list = getMothList(dateY, dateM)
.map(e => !e ? e : e.map(day => {
var cat_date = this.data.cat_date
return !day ? day : {
...day,
className: this.data.chckin_list.indexOf(day.date) != -1 ? 'checkin' : '',
sign: day.date == [cat_date.y, cat_date.m, cat_date.d].join('/'),
maxToday: +(Date.UTC(day.date.split('/')[0], day.date.split('/')[1] - 1, +(day.date.split('/')[2])))
> Date.UTC(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
}
}))
this.setData(({
dateY,
dateM,
date_list,
}))
// 获取月和修改的时候,获取签到列表
this.setSign(dateY, dateM)
// console.log(date_list)
},
|
然后会注意到,这里有一个chckin_list,这个就是要渲染出来的啦。 view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < view class = "week" >
< view class = "flex" wx:for = "{{date_list}}" wx:key = "index" wx:for-item = "row" >
< view
class = "day {{day.maxToday ? 'maxToday' : ''}}"
wx:for = "{{row}}" wx:for-index = "row_idx" wx:for-item = "day" wx:key = "row_idx"
bind:tap = "tapDay"
data-day = "{{day.date}}"
>
< block wx:if = "{{day}}" >
< text class = "block to_day_block {{day.sign ? 'select_date' : ''}}" wx:if = "{{toDay == day.date}}" >今</ text >
< text class = "block {{day.sign ? 'select_date' : ''}}" wx:else>{{day.number}}</ text >
</ block >
< view wx:if = "{{day.className}}" class = "{{day.className}}" >已签</ view >
</ view >
</ view >
</ view >
|
上面是我的业务逻辑,其实只需要if,day就行了,因为除了空的,其他都需要渲染。但是一般业务也有是否签到啊,今天以后的灰色不可点击啊(这里没有不可点击是因为用css禁用点击)
其他
之所以没放css,大家css还是自己写吧,如果真有需要,在下面评论。
哦, 如果要看效果,去小程序里面搜索《初九背单词》,点击日历(一个是首页完成今日任务,一个是我的->背单词天数)
(如果有需要,我可以说下签到后台是怎么做的,nodejs)
--好了--
就这样了,晚安
--- 更新部分---
(楼下有人提醒(毛毛饭),3月最后一个31号的不见了,我检查了下,发现被剪切了,因为5 * 7并不能完整展示出来)
修复后的图
改动部分就是,动态加载行。
基于上面的代码,添加一个判断
先在前面的35改成6*7。因为多加了一行。 然后再判断是否有空余位置,去掉即可。
1 | row.map(e => e || '').join('') !== ''
|
--完--
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~