在小程序中完成日历选择日期的功能(显示当前月份日历、上下月份日历查询、回到今天),效果如下
涉及到的知识点也不多,使用JavaScript提供的Date对象及其方法
1.获取当前年、月、日数据
let year = date.getFullYear()
let month = date.getMonth() // 月份的区间为 0-11
let day = date.getDate()
2.获取当前月份总天数。较为简单的方法是将12个月分别对应的天数存入数组中,再根据平年闰年判断二月份是28天还是29天。这里推荐一种更为简便的方法,在new Date()构造函数中,将当前月份+1,day设为0,getDate()获取的就是当前月份的总天数
// 月份总天数
let days = new Date(year, month + 1, 0).getDate()
3.获取当前月份的一号是星期几。星期的区间 0 - 6,0代表星期日
let whichDay = new Date(year, month, 1).getDay()
4.将当前月份总天数存入数组。这里以星期天的起点,如果当前月份的第一天不是星期天,数组前面需要补上空元素
// 存放日期数组
let dayList = []
// 补空
for (let j = 0; j < whichDay; j++) {
let obj = { 'day': '' };
dayList.push(obj)
}
for (let i = 1; i <= days; i++) {
let obj = {
'day': i,
}
dayList.push(obj)
}
5.月份切换。同样使用new Date()构造函数,只需传入year、month+/-1。例如2019年1月获取上一个月的数据,new Date(2019, 0-1);2019年1月获取下一个月的数据,new Date(2019, 0+1);
let date = new Date(year, month + flag) // flag代表增加或减少的月份
let new_year = date.getFullYear()
let new_month = date.getMonth()
以下是小程序项目个文件代码。打包文件下载地址:小程序日历组件
.wxml
<!-- 日期选择 tab -->
<view class="date-select bordertop" wx:if="{{yanse_column == 0}}">
<view class="date-box">
<view class="date" catchtap="dayShow">
<text class="day">{{day}} </text>/ {{_year}}-{{_month + 1}}
</view>
<image class="date-icon" src="../../assets/icon/icon_jt_pre@2x.png" mode="aspectFill"></image>
<view class="today" catchtap="todayDate">今天</view>
</view>
</view>
<!-- 日期选择 -->
<view class="date-wrap {{dayShow ? 'date-wrap-active':''}}">
<view class="dw-top">
<view class="dw-year-month">{{year_month}}</view>
<image class="dw-arrow-left" src="../../assets/icon/icon_xzyf_left@2x.png" mode="aspectFill"></image>
<image class="dw-arrow-right" src="../../assets/icon/icon_xzyf_right@2x.png" mode="aspectFill"></image>
<view class="dw-btn dw-btn-left" catchtap="switchMonth" data-index="-1"></view>
<view class="dw-btn dw-btn-right" catchtap="switchMonth" data-index="1"></view>
</view>
<view class="dw-week">
<view>日</view>
<view>一</view>
<view>二</view>
<view>三</view>
<view>四</view>
<view>五</view>
<view>六</view>
</view>
<!-- 日期 dl-today -->
<view class="date-list">
<view class="dl-li">
<block wx:for="{{dayList}}" wx:key="{{index}}">
<view
class="dl-item {{item['class']}}"
data-day="{{item['day']}}"
data-clazz="{{item['class']}}"
catchtap="selectDay"
>
{{item['day']}}
</view>
</block>
</view>
</view>
</view>
<!-- 阴影 -->
<view class="date-wrap-shadow" wx:if="{{dayShow}}" catchtap="close_dayShow"></view>
.css
page {
background: #f1f1f1;
}
/* start 日期选择 */
.date-select {
width: 100%;
height: 120rpx;
font-size: 0;
background: #ffffff;
box-sizing: border-box;
z-index: 20;
}
.date-box {
position: relative;
}
.date {
display: inline-block;
margin-top: 24rpx;
margin-left: 30rpx;
font-family: PingFangSC-Medium;
font-size: 24rpx;
color: #000000;
border-right: 4rpx solid transparent;
}
.day {
font-family: PingFangSC-Medium;
font-size: 60rpx;
}
.today {
position: absolute;
top: 44rpx;
right: 30rpx;
font-family: PingFangSC-Regular;
font-size: 30rpx;
color: #808080;
}
.date-icon {
display: inline-block;
width: 19rpx;
height: 16rpx;
}
.date-wrap {
position: fixed;
width: 100%;
top: -1000rpx;
background: #ffffff;
transition: top 0.3s ease;
z-index: 10;
}
.date-wrap-active {
top: 120rpx;
}
.dw-top {
position: relative;
width: 100%;
height: 88rpx;
}
.dw-year-month {
position: absolute;
top: 0;
left: 0;
width: 100%;
text-align: center;
height: 88rpx;
line-height: 88rpx;
font-family: PingFangSC-Regular;
font-size: 30rpx;
color: #1D1D1D;
}
.dw-top > image {
position: absolute;
top: 32rpx;
display: block;
width: 22rpx;
height: 22rpx;
}
.dw-arrow-left {
left: 120rpx;
}
.dw-arrow-right {
right: 120rpx;
}
.dw-btn {
position: absolute;
top: 0;
width: 100rpx;
height: 88rpx;
}
.dw-btn-left {
left: 85rpx;
}
.dw-btn-right {
right: 85rpx;
}
.dw-week {
padding: 0 30rpx;
width: 100%;
height: 60rpx;
line-height: 60rpx;
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #808080;
box-sizing: border-box;
}
.dw-week > view {
display: inline-block;
vertical-align: top;
margin-right: 35rpx;
max-width: 68rpx;
width: 68rpx;
text-align: center;
}
.dw-week > view:last-child {
margin-right: 0;
}
.dl-li {
padding: 0rpx 30rpx 10rpx;
width: 100%;
font-family: PingFangSC-Regular;
font-size: 30rpx;
color: #1D1D1D;
box-sizing: border-box;
}
.dl-item {
margin-top: 16rpx;
display: inline-block;
vertical-align: top;
margin-right: 35rpx;
width: 68rpx;
height: 68rpx;
line-height: 68rpx;
text-align: center;
}
.dl-item:nth-child(7n) {
margin-right: 0;
}
.dl-today {
font-family: PingFangSC-Regular;
font-size: 15px;
color: #FFFFFF;
border-radius: 50%;
background: #21316A;
}
.dl-active {
color: #1D1D1D;
}
.dl-disable {
color: #808080;
}
.date-wrap-shadow {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .5);
z-index: 5;
}
/* end 日期选择 */
.js
Page({
/**
* 页面的初始数据
*/
data: {
yanse_column: 0,
year_month: '',
dayShow: false
},
/**
* 获取今天的数据
*/
todayDate () {
let date = new Date()
let year = date.getFullYear()
let month = date.getMonth()
let day = date.getDate()
day = day < 10 ? '0' + day : day
this.monthDaysUpdate(year, month)
this.setData({
_year: year,
_month: month,
year: year,
month: month,
day: day,
year_month: year + '年' + (month + 1) + '月'
})
},
/**
* 年、月切换
*/
yearMonthUpdate (flag) {
let year = this.data.year
let month = this.data.month
let date = new Date(year, month + flag)
year = date.getFullYear()
month = date.getMonth()
this.monthDaysUpdate(year, month)
this.setData({
year: year,
month: month,
year_month: year + '年' + (month + 1) + '月'
})
},
/**
* 月份天数
* new Date: 把月份设置成下一个月,日期设置成 0,getDate()就获取这个月份的天数
*/
monthDaysUpdate (year, month) {
// 月份总天数
let days = new Date(year, month + 1, 0).getDate()
// 今天的日期
let currYear = new Date().getFullYear()
let currMonth = new Date().getMonth()
let today = new Date().getDate()
// 月份第一天是星期几
let whichDay = new Date(year, month, 1).getDay()
// 存放日期数组
let dayList = []
// 补空
for (let j = 0; j < whichDay; j++) {
let obj = { 'day': '' };
dayList.push(obj)
}
for (let i = 1; i <= days; i++) {
let obj = {
'day': i,
};
if ((i < today && month <= currMonth && year <= currYear) || (month < currMonth && year <= currYear) || (year < currYear)) {
obj['class'] = 'dl-active' // 过去的天数
}
else if (i === today && month === currMonth && year === currYear) {
obj['class'] = 'dl-today'
obj['day'] = '今天'
}
else if (i > today && month >= currMonth && year >= currYear) {
obj['class'] = 'dl-disable' // 未来的天数
}
else {
obj['class'] = 'dl-disable' // 未来的天数
}
dayList.push(obj)
}
this.setData({
dayList: dayList
})
},
/**
* 月份切换
* index: -1 (前一个月) 1 (后一个月))
*/
switchMonth (event) {
let index = event.currentTarget.dataset.index
if (parseInt(index) === -1) {
this.yearMonthUpdate(-1)
}
else if (parseInt(index) === 1) {
this.yearMonthUpdate(1)
}
},
/**
* 选择日期
*/
selectDay (event) {
let day = event.currentTarget.dataset.day
let clazz = event.currentTarget.dataset.clazz
let year = this.data.year
let month = this.data.month
if (clazz.indexOf('dl-disable') === -1) {
if (day === '今天') {
day = new Date().getDate()
}
day = day < 10 ? '0' + day : day
this.setData({
_year: year,
_month: month,
day: day,
dayShow: false
})
}
wx.pageScrollTo({
scrollTop: 0,
duration: 0
})
},
/**
* 日期面板展开
*/
dayShow () {
let dayShow = this.data.dayShow
dayShow = dayShow ? false : true
this.setData({
dayShow: dayShow
})
},
/**
* 日期面板关闭
*/
close_dayShow () {
this.setData({
dayShow: false
})
},
/**
*
*/
})