微信小程序简略日历实现(公历)
周六加班的时候,忽然想看看日历是怎么实现的,就试着写了一下。
--------------------------分割线--------------------------
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;}
--------------------------分割线--------------------------
阐明:只给今日加了蓝色背景,日历点击事件或者加备忘什么的没写,只写了根本款式,要写重要日子或者备忘之类的标记,可依据后盾返回数据给对应那天加上备忘标记,再写个小红点的款式即可。(临时看起来没什么问题,如有大佬发现问题,烦请回复,谢谢)
效果图: