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

今日发量一100 -
微信小程序简单日历实现(公历)
微信小程序简单日历实现(公历)

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

// pages/calendar/calendar.js
Page({

  /**
   * 页面的初始数据
   */
  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天
    }else {//平年
      maxDayList[1] = 28;//2月份28天
    }
    this.setData({maxDayList});
    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 >
  <view >
    <view >
      <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 >
      <view   wx:for="{{week}}" wx:key="index">{{item}}</view>
    </view>
    <view  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"
       >
        <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;
}

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

特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

Tags 标签

javascript前端css微信小程序

扩展阅读

加个好友,技术交流

1628738909466805.jpg