前言概述
本文介绍项目中常用到的日期格式--日历(总是显示一个月有效期选择),该实例分显示页面和日期组件页面两个页面:
实现过程
一、日期组件页面
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'实现高亮效果;
class= <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) }) }})