微信小程序简略日历实现(公历)

周六加班的时候,忽然想看看日历是怎么实现的,就试着写了一下。
--------------------------分割线--------------------------
JS局部

// pages/calendar/calendar.jsPage({  /**   * 页面的初始数据   */  data: {    week: ["一", "二", "三", "四", "五", "六", "日"],//星期    maxDayList: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],//一年12个月,每个月的天数,初始化都给平年    nowYear: new Date().getFullYear(),//以后年份    nowMonth: new Date().getMonth()+1,//以后月份    totalDay: [],//日历天数  },  /**   * 切换年、月   */  changeDate(e) {    let type = e.currentTarget.dataset.type;    let nowYear = this.data.nowYear;    let nowMonth = this.data.nowMonth;    switch(type) {      case "preYear": //上一年        nowYear -= 1;        this.setData({nowYear});        break;      case "preMonth": //上一月        nowMonth -= 1;        if(nowMonth <= 0) {          nowMonth = 12;          nowYear -= 1;        }        break;      case "nextMonth": //下一月        nowMonth += 1;        if(nowMonth >= 13) {          nowMonth = 1;          nowYear += 1;        }        break;      case "nextYear": //下一年        nowYear += 1;        break;    }    this.setData({nowYear, nowMonth});    this.initCalendar();  },  /**   * 初始化日历   */  initCalendar() {    let maxDayList = this.data.maxDayList;    let year = this.data.nowYear, month = this.data.nowMonth;    if((year%4 == 0 && year%100 != 0) || year%400 == 0) {//计算以后年是不是平年,规定:能被4整除且不被100整除,或者能被400整除的年份      maxDayList[1] = 29;//2月份29天    }    let firstDayWeek = new Date(year + "-" + month + "-1").getDay() ;//以后月的1号是星期几    firstDayWeek = firstDayWeek > 0 ? firstDayWeek : 7;//星期日从0转成7    let endDayWeek = new Date(year + "-" + month + "-" +maxDayList[month - 1]).getDay();//以后月最初一天是星期几    endDayWeek = endDayWeek > 0 ? endDayWeek : 7;//星期日从0转成7    let beforArr = [], afterArr = [];//beforArr:本月1号之前须要补充上个月月尾几天,afterArr:本月尾补充下个月月初几天    //求出补充的上个月的日子    for(let i=0; i<firstDayWeek-1; i++) {//找出1号之前的空缺上个月的尾数日,比方明天是周三,则i=3-1, 取前两天的日子      let deffTime = (i+1)*24*60*60*1000; //缺的天数的毫秒值      let firstTime = new Date(year + "-" + month + "-1").getTime();//本月1号的毫秒值      beforArr[i] = {otherMonth: true, day: new Date(firstTime - deffTime).getDate()};//从对应月份的尾数天开始存,比方31,30,29...     }    beforArr = beforArr.reverse();//将补的上月的日子翻转    //求出补充的下个月的日子    for(let i=0; i<7-endDayWeek; i++) {//找出月尾对应的星期几,看看到周日还差几天就从下个月月初补几天      afterArr[i] = {otherMonth: true, day: i+1};    }    let nowMonthArr = [];//以后月所有日子    for(let i=0; i<maxDayList[month - 1]; i++) {      nowMonthArr[i] = {day: i+1};      if(year == new Date().getFullYear()) {//如果切换到了本年本月本日,则凸显今日        if(month == new Date().getMonth() + 1) {          if(new Date().getDate() == i+1) {            nowMonthArr[i].today = true;          }        }      }    }    let totalDayList = beforArr.concat(nowMonthArr).concat(afterArr);//将所有日期拼接    let totalDay = [], arr = [];//totalDay:最终用来展现数据,arr:用来宰割每一周的日子    for(let i=0; i<totalDayList.length; i++) {      arr.push(totalDayList[i]);      if((i+1)%7 == 0) {//每7天存为一组        totalDay.push(arr);        arr = [];//存完清空      }    }    this.setData({totalDay});  },  /**   * 生命周期函数--监听页面加载   */  onLoad: function (options) {  },  /**   * 生命周期函数--监听页面首次渲染实现   */  onReady: function () {  },  /**   * 生命周期函数--监听页面显示   */  onShow: function () {    this.initCalendar();  },  /**   * 生命周期函数--监听页面暗藏   */  onHide: function () {  },  /**   * 生命周期函数--监听页面卸载   */  onUnload: function () {  },  /**   * 页面相干事件处理函数--监听用户下拉动作   */  onPullDownRefresh: function () {  },  /**   * 页面上拉触底事件的处理函数   */  onReachBottom: function () {  },  /**   * 用户点击右上角分享   */  onShareAppMessage: function () {  }})

--------------------------分割线--------------------------
wxml局部
几个image按钮按程序是上一年、上个月、下个月、下一年,找不图片的能够用文字代替

<!--pages/calendar/calendar.wxml--><view class="calendar-page">  <view class="calendar">    <view class="btn-row">      <image src="../../image/mine/calendar/arrow-left2.png" bindtap="changeDate" data-type="preYear"></image>      <image src="../../image/mine/calendar/arrow-left.png" bindtap="changeDate" data-type="preMonth"></image>      <view>{{nowYear + "-" + (nowMonth >= 10 ? nowMonth : "0" + nowMonth)}}</view>      <image src="../../image/mine/calendar/arrow-right.png" bindtap="changeDate" data-type="nextMonth"></image>      <image src="../../image/mine/calendar/arrow-right2.png" bindtap="changeDate" data-type="nextYear"></image>    </view>    <view class="week-row">      <view class="week-item"  wx:for="{{week}}" wx:key="index">{{item}}</view>    </view>    <view class="day-row" wx:for="{{totalDay}}" wx:for-item="item" wx:for-index="index" wx:key="index">      <view wx:for="{{item}}" wx:for-item="subItem" wx:for-index="subIndex" wx:key="subIndex"      class="day-item {{subItem.today?'day-today':''}}{{subItem.otherMonth?'day-otherMonth':''}}" >        <text>{{subItem.day}}</text>      </view>    </view>  </view></view>

--------------------------分割线--------------------------
css局部

/* pages/calendar/calendar.wxss */page {  height: 100%;  width: 100%;  background: #f3f5f9;}.calendar-page {  width: 100%;  height: 100%;  padding: 30rpx;  box-sizing: border-box;}.calendar {  border-radius: 30rpx;  background: #fff;  box-shadow:0rpx 24rpx 38rpx rgba(60, 128, 209, 0.09);  box-sizing: border-box;  padding: 30rpx;}.btn-row {  height: 70rpx;  line-height: 70rpx;  text-align: center;  font-size: 24rpx;  margin-bottom: 20rpx;}.btn-row view {  display: inline-block;  vertical-align: middle;  margin-right: 30rpx;  margin-left: 15rpx;}.btn-row image {  vertical-align: middle;  margin-right: 15rpx;  width: 25rpx;  height: 25rpx;  padding: 5rpx 10rpx;  border-radius: 10rpx;  border: 1rpx solid #00a8ff;}.week-row {  width: 100%;  display: flex;  justify-content: space-between;  align-items: center;}.week-item {  width: 50rpx;  height: 50rpx;  text-align: center;  line-height: 50rpx;  font-size: 24rpx;  font-weight: bold;  color: #000000;}.day-row {  width: 100%;  display: flex;  justify-content: space-between;  align-items: center;  margin-top: 20rpx;}.day-item {  width: 50rpx;  height: 50rpx;  text-align: center;  line-height: 50rpx;  font-size: 24rpx;  font-weight: bold;  color: #000000;  border-radius: 50%;  box-sizing: border-box;}.day-today {  background: #00a8ff;  color: #fff;}.day-otherMonth {  color: #cdcdcd;}

--------------------------分割线--------------------------
阐明:只给今日加了蓝色背景,日历点击事件或者加备忘什么的没写,只写了根本款式,要写重要日子或者备忘之类的标记,可依据后盾返回数据给对应那天加上备忘标记,再写个小红点的款式即可。(临时看起来没什么问题,如有大佬发现问题,烦请回复,谢谢)
效果图: