微信小程序日历(可单选或复选时间)
html部分
<view class="calendar custom-class">
<view class="month">
<picker bindchange="bindPickerChange" value="{{showYear+'-'+showMonth}}" fields='month' mode="date" end="{{currentTime}}">
<text class="title">{{showYear}}年 {{showMonth}}月</text>
</picker>
<view class="icon_arrows disflex">
<image src="../../../images/icon_arrows_left.png" bindtap="getLastMonth" class="icon_arrows_left icon_arrows_tip">
</image>
<image src="../../../images/icon_arrows_left.png" class="icon_arrows_right icon_arrows_tip" bindtap="getNextMonth"
wx:if='{{currentYear > showYear || (currentYear === showYear && currentMonth > showMonth)}}'></image>
<image src="../../../images/icon_arrows_right@2x.png" class="icon_arrows_tip" wx:else></image>
</view>
</view>
<view class="mt-32 week_list">
<text wx:for="{{week}}" class="c-9f9f9f">{{item}}</text>
</view>
<view class="day_list">
<text wx:for="{{dateList}}"
class="date_item {{(item.timestamp === endTimestamp || item.timestamp === startTimestamp)?'selectDate_item':''}} {{(item.timestamp < endTimestamp && item.timestamp >= startTimestamp) ? 'selectDateBg' : ''}} c-6b6b6b"
bindtap="selectDate" data-date="{{item.label}}"><text class="selectDate"
wx:if='{{item.timestamp === endTimestamp || item.timestamp === startTimestamp}}'></text>{{item.label}}<text
class="circular {{item.status === '0' ? 'circular_normal':''}}" wx:if='{{item.status}}'></text></text>
</view>
</view>
js
// components/shopLists/index.js
Component({
externalClasses: ['custom-class'],
properties: {
type: {
type: String,
value: 'single', //single表示单选,range表示选择日期区间
},
monthTranslate: { //日历上的红蓝点
type: Object,
value: {}
}
},
data: {
week: ['日', '一', '二', '三', '四', '五', '六'],
dateList: [],
showYear: '', //页面上展示的年
showMonth: '', //页面上展示的月
showDay: '', //页面上展示的日
startSelectYear: '', //开始选中的年
startSelectMonth: '', //开始选中的月
startSelectDay: 0, //开始选中的日
currentYear: '', //当前年
currentMonth: '', //当前月
currentTime: '2021-01', //当前年月日
startTimestamp: '', //开始的时间戳
endTimestamp: '', //结束的时间戳
},
lifetimes: {
ready() {
const now = new Date();
const startTimestamp = Date.parse(new Date(now.getFullYear(), now.getMonth(), now.getDate()));
this.setData({
currentYear: now.getFullYear(),
currentMonth: now.getMonth() + 1,
startTimestamp
})
this.triggerEvent('getCalendarTime', {
startTime: this.uDateFormat(startTimestamp),
endTime: this.uDateFormat(startTimestamp)
})
this.getCurrentData();
this.getDay()
}
},
observers: {
monthTranslate() {
this.data.dateList.some(val => {
Object.keys(this.data.monthTranslate).some(item => {
if (val.label * 1 == item) {
val.status = this.data.monthTranslate[item].toString()
delete this.data.monthTranslate[item];
return
}
})
if (Object.keys(this.data.monthTranslate).length === 0) {
return
}
})
this.setData({
dateList: this.data.dateList
})
}
},
methods: {
getDay() {
const {
showYear,
showMonth,
showDay
} = this.data;
var firstDay = new Date(`${showYear}, ${showMonth}, 1`).getDay(); //获得每月1号是星期几
let days = new Date(showYear, showMonth, 0).getDate(); //获取当月多少天
this.data.dateList = [];
for (let s = 1; s <= firstDay; s++) {
this.data.dateList.push({
label: '',
timestamp: 0
})
}
for (let i = 1; i <= days; i++) {
this.data.dateList.push({
label: i < 10 ? '0' + i : i,
timestamp: Date.parse(new Date(`${showYear}, ${showMonth}, ${i}`))
})
}
this.setData({
dateList: this.data.dateList,
showYear,
showMonth
})
if (this.data.startSelectYear === '') {
this.data.startSelectYear = showYear
this.data.startSelectMonth = showMonth
this.data.startSelectDay = showDay
}
this.triggerEvent("changTime", {
showYear,
showMonth
})
},
getCurrentData() { //获取当前日期,初始化使用
const date = new Date();
this.data.showYear = date.getFullYear();
this.data.showMonth = date.getMonth() + 1;
this.data.showDay = date.getDate();
},
getNextMonth() { //获取下个月
if (this.data.showMonth < 12) {
this.data.showMonth += 1;
} else {
this.data.showMonth = 1;
this.data.showYear += 1;
}
this.getDay();
},
bindPickerChange(e) { //下拉选择年月
const {
value
} = e.detail;
this.data.showYear = value.split('-')[0] * 1;
this.data.showMonth = value.split('-')[1] * 1;
this.getDay();
},
getLastMonth() { //获取上个月
if (this.data.showMonth !== 1) {
this.data.showMonth -= 1;
} else {
this.data.showMonth = 12;
this.data.showYear -= 1;
}
this.getDay();
},
selectDate(e) {
const {
date
} = e.currentTarget.dataset;
if (!date) {
return;
}
const {
showYear,
showMonth,
startSelectYear,
startSelectMonth,
startSelectDay,
endTimestamp
} = this.data;
const currentTimestamp = Date.parse(new Date(showYear, showMonth - 1, date * 1)); //当前选中的时间戳
if (this.data.type === 'single') { //单选日期
this.setData({
startTimestamp: currentTimestamp,
endTimestamp: currentTimestamp
})
this.triggerEvent('getCalendarTime', {
startTime: this.uDateFormat(this.data.startTimestamp),
endTime: this.uDateFormat(this.data.endTimestamp)
})
return
}
const startTimestamp = Date.parse(new Date(startSelectYear, startSelectMonth - 1, startSelectDay * 1)); //已经选择的开始时间的时间戳
if (this.data.startSelectYear === '' || currentTimestamp < startTimestamp || (currentTimestamp > startTimestamp && currentTimestamp < endTimestamp)) {
this.setData({
startTimestamp: currentTimestamp,
endTimestamp: this.data.endTimestamp >= currentTimestamp ? this.data.endTimestamp : currentTimestamp
})
this.data.startSelectYear = showYear;
this.data.startSelectMonth = showMonth;
this.data.startSelectDay = date;
if (currentTimestamp > startTimestamp && currentTimestamp < endTimestamp) { //如果选择了开始和结束日期中间的日期,则初始化日期
this.setData({
endTimestamp: currentTimestamp
})
}
this.triggerEvent('getCalendarTime', {
startTime: this.uDateFormat(this.data.startTimestamp),
endTime: this.uDateFormat(this.data.endTimestamp)
})
return;
}
this.setData({
endTimestamp: currentTimestamp //结束的时间戳
})
this.triggerEvent('getCalendarTime', {
startTime: this.uDateFormat(this.data.startTimestamp),
endTime: this.uDateFormat(this.data.endTimestamp)
})
},
// 时间戳转日期时间格式: yyyy-MM-dd
uDateFormat(timestamp) {
return this.uMoment(timestamp).format('yyyy-MM-dd')
},
uMoment(timestamp) {
const leftPad = (num) => {
if (num < 10) {
return `0${num}`
}
return `${num}`
}
const date = new Date(timestamp)
return {
format(pattern) {
const str = typeof pattern === 'string' ? pattern : 'yyyy-MM-dd'
if (!Number.isNaN(date.getTime())) {
return str
.replace(/yyyy/i, leftPad(date.getFullYear()))
.replace(/MM/, leftPad(date.getMonth() + 1))
.replace(/dd/i, leftPad(date.getDate()))
.replace(/hh/i, leftPad(date.getHours()))
.replace('mm', leftPad(date.getMinutes()))
.replace(/ss/i, leftPad(date.getSeconds()))
}
return ''
}
}
}
}
})
css
page {
background: #f6f6f6;
}
.calendar {
background-color: #fff;
border-radius: 10rpx;
padding: 32rpx 64rpx 48rpx;
}
.calendar .month {
display: flex;
justify-content: space-between;
align-items: center;
}
.calendar .month .title {
font-size: 32rpx;
font-weight: 500;
line-height: 48rpx;
color: #262626;
}
.calendar .month .icon_arrows .icon_arrows_left {
margin-right: 62rpx;
}
.calendar .month .icon_arrows .icon_arrows_right {
transform: rotate(180deg);
}
.calendar .week_list {
padding-bottom: 16rpx;
display: flex;
}
.calendar .week_list text {
width: 16.66%;
}
.calendar .week_list text:last-child {
width: auto;
}
.calendar .day_list {
flex-wrap: wrap;
display: flex;
}
.calendar .day_list text {
width: 15.6%;
flex-shrink: 0;
height: 80rpx;
line-height: 80rpx;
}
.calendar .day_list text:nth-child(7n) {
width: 38rpx;
text-align: right;
}
.calendar .day_list .date_item {
position: relative;
}
.calendar .day_list .date_item:nth-child(7n) {
color: #cecece;
}
.calendar .day_list .date_item:nth-child(7n+1) {
color: #cecece;
}
.calendar .day_list .selectDate_item {
z-index: 2;
color: #fff !important;
}
.calendar .day_list .selectDate_item .selectDate {
width: 80rpx;
height: 80rpx;
background: #4E88FF;
position: absolute;
border-radius: 100%;
z-index: -1;
top: 0;
left: -22rpx;
}
.calendar .day_list .selectDate_item .circular_normal {
background: #fff;
}
.calendar .day_list .circular {
width: 8rpx;
height: 8rpx;
background: #FF4400;
border-radius: 8rpx;
display: block;
position: absolute;
bottom: 10rpx;
left: 17rpx;
}
.calendar .day_list .circular_normal {
background: #4E88FF;
}
.calendar .day_list .circular_white {
background: #fff;
}
.calendar .day_list .selectDateBg {
background-color: rgba(78, 136, 255, 0.2);
}
.mt-32 {
margin-top: 32rpx;
}
.c-9f9f9f {
color: #9f9f9f;
}
.c-6b6b6b {
color: #6b6b6b;
}
.icon_arrows_tip {
width: 32rpx;
height: 32rpx;
}
在页面中引入
<calendar monthTranslate='{{monthTranslate}}'></calendar>
//js
Page({
data: {
monthTranslate: {}, //地图上的红蓝点
},
onReady: function (options) {
setTimeout(() => { //模拟接口拿取红蓝点
this.setData({
monthTranslate: {
4: 1,
6: 1,
12: 0
}
})
}, 1000)
},
})
//JSON引入组件
{
"navigationBarTitleText": "日历",
"usingComponents": {
"calendar": "../components/calendar/calendar"
}
}
点击下载DOM