示例简介
本文介绍项目中常用到的日期格式--日历(总是显示一个月有效期选择),该实例分显示页面和日期组件页面两个页面:
实现过程
一、日期组件页面
1、先实现页面效果,文件*.wxml和*.wxss代码如下:
1)需求只需要显示每个月自己的日期,由于该算法也显示了非自己月份的日期,所以需要过滤掉非当月的日期,在wxml使用wx:if="{{item.year === lists.dateYear && item.month === lists.dateMonth}}";
2)item.isDisable ? 'opacity30' : (item.year === selectDay.year && item.month === selectDay.month && item.day === selectDay.day?'select':'')实现原理,判断是否有效期(isDisable ),非有效期增加'opacity30'实现透明度30%效果;而有效期判断是否被选中,选中则增加'select'实现高亮效果;
<view class="calendar">
<!-- 日历头部 -->
<view class="calendar-week">
<view class="view">日</view>
<view class="view">一</view>
<view class="view">二</view>
<view class="view">三</view>
<view class="view">四</view>
<view class="view">五</view>
<view class="view">六</view>
</view>
<view wx:for="{{dateList}}" wx:for-item="lists" wx:key="dateList" class="day-box">
<!-- 年月份信息 -->
<view class="title">
<view>{{lists.dateYear}}年{{lists.dateMonth>9?lists.dateMonth:"0"+lists.dateMonth}}月</view>
</view>
<!-- 日历主体 -->
<view class="calendar-main">
<view wx:for="{{lists.list}}" wx:key="index" class="day">
<view wx:if="{{item.year === lists.dateYear && item.month === lists.dateMonth}}" class="day-item {{item.isDisable ? 'opacity30' : (item.year === selectDay.year && item.month === selectDay.month && item.day === selectDay.day?'select':'')}}" catchtap="selectChange" data-day="{{item.day}}" data-year="{{item.year}}" data-month="{{item.month}}" data-date-string="{{item.dateString}}" data-week-day="{{item.weekDay}}" data-isdisable="{{item.isDisable}}">
<view class="text {{item.isWeekend ? 'orange' : (item.isToday ? 'blue' : '')}}">
{{item.day}}
</view>
<view class="remark blue" wx:if="{{item.isToday}}">今天</view>
<view class="remark orange" wx:if="{{item.isWeekend}}">休</view>
</view>
</view>
</view>
</view>
</view>
.calendar .title {
font-weight: bold;
text-align: center;
padding: 20rpx 0 0;
}
.calendar .calendar-week {
display: flex;
line-height: 50rpx;
height: 50rpx;
color: #808080;
background-color: #F3F6F8;
padding: 0 25rpx;
}
.calendar .calendar-week .view {
width: 100rpx;
text-align: center;
}
.calendar .calendar-main {
padding: 10rpx 25rpx 0;
display: flex;
flex-wrap: wrap;
}
.calendar .calendar-main .day {
width: 100rpx;
text-align: center;
height: 100rpx;
position: relative;
}
.calendar .calendar-main .day .day-item {
height: 70rpx;
padding-top: 30rpx;
}
.calendar .calendar-main .day .other-month {
color: #ccc;
display: none;
}
.calendar .calendar-main .day .remark {
font-size: 20rpx;
}
.calendar .calendar-main .day .blue {
color: #3D7AF5;
}
.calendar .calendar-main .day .orange {
color: #FA7014;
}
.calendar .calendar-main .day .opacity30 {
opacity: 0.3;
}
.calendar .calendar-main .day .select {
background-color: #3D7AF5;
border-radius: 8rpx;
}
.calendar .calendar-main .day .select .text {
color: #fff;
}
.calendar .calendar-main .day .select .remark {
color: #fff;
}
2、接下来实现交互逻辑,文件*.js代码实现如下:
1)dateInit函数用于获取渲染的日历主体信息和所需要的data各种数据;
2)onLoad实现获取当天日期并渲染主体数据,加了判断是否选中过日期来变化高亮日期天数;
3)selectChange函数用于点击后把选中日期数据传回上一页,并跳转到上一页。
import util from '../../utils/util.js'
Page({
/**
* 页面的初始数据
*/
data: {
dateList: [], // 日历主体渲染数组
nowDay: {}, // 今天日期
selectDay: {}, // 选中时间
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 获取当前日期信息
let now = new Date();
let nowDay = {
year: now.getFullYear(),
month: now.getMonth() + 1,
day: now.getDate()
}
let selectDay = nowDay;
// 存在选择数据情况
if (options.selectDay != 0) {
selectDay = JSON.parse(options.selectDay);
}
this.setData({
nowDay,
selectDay
});
this.dateInit(nowDay.year, nowDay.month);
},
// 日历主体的渲染方法
dateInit(setYear, setMonth) {
let dateList = []; // 需要遍历的日历数组数据
// 循环两个月数据(2)
for (let i = 0; i < 2; i++) {
let now = new Date(setYear, setMonth - 1 + i); // 当前月份的1号
let startWeek = now.getDay(); // 目标月1号对应的星期
let dayNum = new Date(setYear, setMonth + i, 0).getDate(); // 当前月有多少天
let forNum = Math.ceil((startWeek + dayNum) / 7) * 7; // 当前月跨越的周数
let dateObj = {};
let list = [];
for (let j = 0; j < forNum; j++) {
const now2 = new Date(now);
now2.setDate(j - startWeek + 1);
let obj = {};
let day = now2.getDate();
let month = now2.getMonth() + 1;
let year = now2.getFullYear();
let weekDay = now2.getDay();
let nowDay = this.data.nowDay;
let isDisable;
// 用于判断本月小于今天,下个月大于今天的日期不能选择
if (month == nowDay.month) {
isDisable = (day < nowDay.day) ? true : false;
} else {
isDisable = (day >= nowDay.day) ? true : false;
}
obj = {
day,
month,
year,
weekDay,
dateString: util.formatTime(now2),
isToday: (year === nowDay.year && month === nowDay.month && day === nowDay.day) ? true : false, // 是否今天
isWeekend: (weekDay === 0 || weekDay === 6) ? true : false, // 是否周末
isDisable
};
list[j] = obj;
}
dateObj = {
dateYear: now.getFullYear(),
dateMonth: now.getMonth() + 1,
list: list
}
dateList.push(dateObj);
}
this.setData({
dateList: dateList
})
},
// 一天被点击时
selectChange(e) {
const weekDay = e.currentTarget.dataset.weekDay;
const isDisable = e.currentTarget.dataset.isdisable;
// 非有效期不能预约
if (isDisable) {
util.showToast('请选择有效期', 'none');
return false;
}
// 周末不能预约
if (weekDay === 0 || weekDay === 6) {
util.showToast('请选择非休息日', 'none');
return false;
}
// 获取星期几
let weeks = util.getWeeks(weekDay);
const year = e.currentTarget.dataset.year
const month = e.currentTarget.dataset.month
const day = e.currentTarget.dataset.day
const dateString = e.currentTarget.dataset.dateString
const selectDay = {
year: year,
month: month,
day: day,
dateString: dateString + ' ' + weeks
}
console.log(selectDay);
this.setData({
selectDay: selectDay
});
// 传数据到上一个页面
let pages = getCurrentPages(); // 获取当前所有页面
let prevPage = pages[pages.length - 2]; // 获取上一个页面并传参
prevPage.setData({
selectDay
});
wx.navigateBack({
delta: 1, // 返回上一级页面
})
}
})
二、显示页面
1、先实现页面效果,文件*.wxml和*.wxss代码如下:
<view class="time-box">
<view class="time-title">预约日期</view>
<view class="picker" bindtap="selectDate">
<text>{{selectDay.dateString ? selectDay.dateString : dateString}}</text>
</view>
</view>
.time-box {
padding: 32rpx 30rpx;
display: flex;
background-color: #fff;
}
.time-box .time-title {
color: #9A9A9A;
margin-right: 73rpx;
width: 200rpx;
}
.time-box .picker {
width: 400rpx;
}
2、接下来实现交互逻辑,文件*.js代码实现如下:
Page({
/**
* 页面的初始数据
*/
data: {
dateString: '2020-09-03 星期四'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
// 选择日期
selectDate: function() {
wx.navigateTo({
url: '../calendarModule/calendarModule?selectDay=' + JSON.stringify(this.data.selectDay ? this.data.selectDay : 0)
})
}
})