小程序手写日历功能

核心就是算出本月一共多少天,第一天星期几,最后一天星期几,然后再根据每周第一天取出来上个月在面板上显示的日期,根据每周最后一天取出下个月显示在面板上的日期,然后每个块放在容器里让他自己排起来就行了。具体步骤如下:

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;
}

  

posted @ 2023-07-31 10:18  大尹  阅读(71)  评论(0编辑  收藏  举报