小程序手写日历功能
核心就是算出本月一共多少天,第一天星期几,最后一天星期几,然后再根据每周第一天取出来上个月在面板上显示的日期,根据每周最后一天取出下个月显示在面板上的日期,然后每个块放在容器里让他自己排起来就行了。具体步骤如下:
1、计算当前月份共有多少天
2、计算当前月第一天是星期几
3、计算当前月最后一天是星期几
4、计算上个月共有多少天
5、计算上个月应该拿出多少天
6、计算下个月应该拿出多少天
这里要注意的主要就是 new Date(year, month, 0).getDate() 这个返回的是month月共有多少天,取7月就传7月。
// index.js // 获取应用实例 const app = getApp() import config from "../../utils/config" import {request} from "../../utils/request"; Page({ data: { year:0, month:0, date:0, weekType:'星期一', beforeMonth:[], //当月日期 currentMonth:[], //上个月日期 afterMonth:[], //下个月日期 weeks:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"], today:'' }, onLoad(options){ var DATE = new Date(), year = DATE.getFullYear(), month = DATE.getMonth() + 1, date = DATE.getDate(),this.setData({ year, month, date, today:`${year}-${month}-${date}` }) if(this.data.weekType == '星期一'){ this.setData({weeks:["星期一","星期二","星期三","星期四","星期五","星期六","星期日"]}) } }, formatZero(data){ return data >= 10 ? data : '0'+data }, getThisMonthDays(year,month){ return new Date(year, month, 0).getDate(); }, compute(year,month){ wx.showLoading() //这里要注意:new Date()时,月份是从0开始的,也就是说算1月的时候其实传的值是0,当然第一个月1-1之后是0正好就是当前年的第一个月,所以不需要考虑切换年的问题 //new Date()传年月日时,如果日传的是0,就会计算当月一共有多少天,内部原因:new Date传2023,2月时,实际上计算的是3月的时间,但是日参数传的是0,那么就是获取的2月的最后一天的时间 var thisMonthDays = this.getThisMonthDays(year,month), //计算当前月有多少天 firstWeek = new Date(year,month-1,1).getDay(), //计算当前月第一天是星期几 lastWeek = new Date(year,month-1,thisMonthDays).getDay(), //计算当前月最后一天是星期几 beforeMonthYear = 0, //上个月是哪年 beforeMonthMonth = 0, //上个月是几月 beforeMonthDays = 0, //上个月一共多少天 afterMonthYear = 0, //下个月是哪年 afterMonthMonth = 0, //下个月是几月 beforeMonth = [], //上个月日期 currentMonth = [], //当月日期 afterMonth = [], //下个月日期 userInfo = wx.getStorageSync('userInfo') if(month == 1){ //如果当前月是1月,那么上个月就是去年的12月,年也要减去1年 beforeMonthYear = year - 1 beforeMonthMonth = 12 afterMonthYear = year afterMonthMonth = month + 1 } if(month == 12) { beforeMonthYear = year beforeMonthMonth = month - 1 afterMonthYear = year + 1 afterMonthMonth = 1 }else{ beforeMonthYear = year beforeMonthMonth = month - 1 afterMonthYear = year afterMonthMonth = month + 1 } beforeMonthDays = this.getThisMonthDays(beforeMonthYear,beforeMonthMonth) //从这里开始分开,看第一天是星期几,星期天什么样,星期一什么样从这里分开就行了,最主要的就是看当月的1号是星期几 // 星期日 星期一 星期二 星期三 星期四 星期五 星期六 // 0 1 2 3 4 5 6 // 星期一 星期二 星期三 星期四 星期五 星期六 星期日 // 1 2 3 4 5 6 7 //每日日历中的参数{year,month,day,format:year-month-day,today:} if(this.data.weekType == '星期日'){ //如果排列的第一天是星期天 //星期天作为第一天,当前月第一天星期几就在前面留出几个空,如当月第一天是星期六,就拿出上星期的6天来补齐。当月第一天是星期天,上个月就不用拿出来补了 // 计算上个月保留的时间 for (let i = 1; i <= firstWeek; i++) { var day = beforeMonthDays - (firstWeek - i) var obj = {year:beforeMonthYear,month:beforeMonthMonth,day:day,format:`${beforeMonthYear}-${beforeMonthMonth}-${day}`,today:false} beforeMonth.push(obj) } //计算下个月保留的时间 var after = 7 - lastWeek - 1 for (let i = 1; i <= after; i++) { var obj = {year:afterMonthYear,month:afterMonthMonth,day:i,format:`${afterMonthYear}-${afterMonthMonth}-${i}`,today:false} afterMonth.push(obj) } }else{ //如果排列的第一天是星期一 // 计算上个月保留的时间 if(firstWeek == 0){ var before = 6 }else{ var before = firstWeek - 1 } for (let i = 1; i <= before; i++) { var day = beforeMonthDays - (before - i) var obj = {year:beforeMonthYear,month:beforeMonthMonth,day:day,format:`${beforeMonthYear}-${beforeMonthMonth}-${day}`,today:false} beforeMonth.push(obj) } //计算下个月保留的时间,这里有点问题,如果最后一天是星期天的话,就不用从下个月再计算了,否则就计算 var after = 7 - lastWeek == 7 ? 0 : 7 - lastWeek for (let i = 1; i <= after; i++) { var obj = {year:afterMonthYear,month:afterMonthMonth,day:i,format:`${afterMonthYear}-${afterMonthMonth}-${i}`,today:false} afterMonth.push(obj) } } //最后计算当月的时间就行 for(let i = 1; i <= thisMonthDays; i++){ var day = i var today = this.data.today == `${year}-${month}-${day}` var obj = {year:year,month:month,day:day,format:`${year}-${month}-${day}`,today,total:0} currentMonth.push(obj) } this.setData({ beforeMonth, currentMonth, afterMonth }) }, monthReduce(){ var month,year if(this.data.month == 1){ month = 12 year = this.data.year - 1 }else{ month = this.data.month -1 year = this.data.year } this.setData({month,year}) this.compute(year,month) }, monthAdd(){ var month,year if(this.data.month == 12){ month = 1 year = this.data.year + 1 }else{ month = this.data.month + 1 year = this.data.year } this.setData({month,year}) this.compute(year,month) } })
<view class="calendar"> <view class="top"> <view class="title">打卡日历</view> <view class="center"> <text class="iconfont icon-zuozuo-" bindtap="monthReduce"></text> <text class="month">{{year}}年-{{month}}月</text> <text class="iconfont icon-youyou-" bindtap="monthAdd"></text> </view> <view class="right" bindtap="togglefold"> <text>{{fold ? '展开' : '收起'}}</text> <text class="iconfont {{fold ? 'icon-xia' : 'icon-shang'}}"></text> </view> </view> <view class="week"> <view class="item" wx:for="{{weeks}}" wx:key="index">{{item}}</view> </view> <scroll-view scroll-y="true" style="{{fold ? 'height:222rpx;' : ''}}"> <view class="days"> <view class="item gray hide" wx:for="{{beforeMonth}}" wx:key="index"> <view class="day">{{item.day}}</view> <view class="detail transparent">{{item.total}}次</view> </view> <navigator url="/pages/sign_in/sign_in?date={{item.format}}" class="item {{item.today ? 'select' : item.total > 0 ? 'work' : 'gray'}}" wx:for="{{currentMonth}}" wx:key="index"> <view class="day">{{item.day}}</view> <view class="detail {{item.total == 0 ? 'transparent' : ''}}">{{item.total}}次</view> </navigator> <view class="item gray hide" wx:for="{{afterMonth}}" wx:key="index"> <view class="day">{{item.day}}</view> <view class="detail transparent">{{item.total}}次</view> </view> </view> </scroll-view> </view>
.calendar,.panel { padding: 20rpx 30rpx 50rpx 30rpx; box-sizing: border-box; background: #fff; border-radius: 20rpx; width: 90%; margin: 10rpx auto; } .calendar .top { display: flex; justify-content: space-between; } .calendar .top .title, .panel .title { font-weight: bold; font-size: 32rpx; } .calendar .top .center { } .calendar .top .center .month{ margin: 0 18rpx; } .calendar .top .right { font-size: 24rpx; color: #9E9E9E; } .calendar .week { display: flex; margin-top:20rpx } .calendar .week .item { flex: 1; font-size: 20rpx; color: #9e9e9e; text-align: center; } .calendar .days { display: flex; flex-wrap: wrap; } .calendar .days .item { width: 14.28571428571429%; display: flex; flex-direction: column; justify-content: center; align-items: center; margin-top: 19rpx; } .calendar .days .item .day { width: 48rpx; height: 48rpx; font-size: 30rpx; text-align: center; line-height: 48rpx; border-radius: 10rpx; font-weight: bold; } .calendar .days .item.gray .day { background: #E0EAFF; color: #BDC4D0; } .calendar .days .item.select .day { background: #EA0000; color: #fff; } .calendar .days .item.work .day { background: #3F58FD; color: #fff; } .calendar .days .item.hide .day { color: transparent; background-color: transparent; } .calendar .days .detail.transparent { color: transparent; } .calendar .days .detail { font-size: 20rpx; color: #9E9E9E; margin-top: 10rpx; }