前言概述
本文介绍项目中常用到的日期格式--月历滑动格式,顶部显示当前月的月历,默认选择当天的日期,且能滑动月历选择需要的日期:
实现过程
1. 先实现页面效果,文件*.wxml和*.wxss代码如下:
1)滑动功能使用组件scroll-view,样式实现参考下面代码;为了实现加载时默认选择当天的日期,可使用组件属性scroll-into-view,属性值“toView”需用setData设置,不然不起作用;
2)item.isDisable ? 'opacity30' : (item.year === selectDay.year && item.month === selectDay.month && item.day === selectDay.day?'select':'')的实现原理,判断是否有效期(isDisable ),非有效期增加'opacity30'实现透明度30%效果;而有效期判断是否被选中,选中则增加'select'实现高亮效果;
class= <view class="tabs-box"> <scroll-view class="time-tabs" scroll-x scroll-into-view="{{toView}}" scroll-with-animation> <view wx:for="{{list}}" wx:key="index" class="day {{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}}" id="{{item.id}}"> <view class="month">{{item.year}}-{{item.month}}view> <view class="text {{item.isWeekend ? 'orange' : ''}}"> {{item.day}} view> <view class="week">{{item.week}}view> view> scroll-view> <view class="remark"><text>滑动选择更多日期text>view> view> <view class="timeList"> <view class="table"> <view class="tr title"> <view class="th first">时间段view> <view class="th center">剩余数view> <view class="th last">操作view> view> <scroll-view scroll-y="true" style="height: {{clientHeight?clientHeight-tabsBoxHeight-titleHeight+'px':'auto'}}"> <view class="tr septalLine" wx:for="{{timeList}}" wx:key="id"> <view class="td first">{{item.time}}view> <view class="td center">{{item.bookingNumber}}view> <view class="td last">预约view> view> scroll-view> view> view>view>
/* 日期选择 */.tabs-box { height: 228rpx;}.time-tabs { white-space: nowrap;}.time-tabs .day { display: inline-block; width: 150rpx; height: 170rpx; text-align: center; position: relative; font-size: 26rpx; border: 2rpx solid #E6E6E6;}.time-tabs .day.opacity30 { opacity: 0.3;}.time-tabs .day .month { color: #E6E6E6; padding: 10rpx 0 14rpx;}.time-tabs .day .text { font-size: 32rpx; color: #343434; font-weight: bold;}.time-tabs .day .week { color: #999; background-color: #F0F3F5; position: absolute; bottom: 0; width: 100%; text-align: center; padding: 8rpx 0;}.time-tabs .day .orange { color: #FA7014;}.time-tabs .day.select { border-color: #3E7AF5;}.time-tabs .day.select .month, .time-tabs .day.select .text { color: #3E7AF5;}.time-tabs .day.select .week { color: #fff; background-color: #3E7AF5;}.remark { color: #9A9A9A; font-size: 26rpx; text-align: center; margin-top: 20rpx;}.remark image { width: 32rpx; height: 14rpx; vertical-align: middle; margin-top: -6rpx;}.remark text { margin: 0 6rpx}/* 预约时间列表 */.table { padding: 0 30rpx;}.table .tr { display: flex; padding: 40rpx 0 30rpx;}.table .tr .th { color: #666; margin-bottom: 10rpx;}.table .tr .th, .table .tr .td { text-align: center;}.table .tr .td { font-size: 32rpx; color: #343434;}.table .tr .first { width: 188rpx;}.table .tr .center { flex: 1;}.table .tr .last { width: 120rpx;}.table .tr .td.last { height: 60rpx; line-height: 60rpx; border: 2rpx solid #3E7AF5; color: #3E7AF5; border-radius: 8rpx; font-size: 28rpx; margin-top: -12rpx;}
2. 接下来实现交互逻辑,文件*.js代码实现如下:
1)dateInit函数用于获取渲染的日历主体信息和所需要的data各种数据;
2)onLoad实现获取当天日期并渲染主体数据,加了判断是否选中过日期来变化高亮日期天数;并计算日期列表的高度,实现只滚动日期列表,不影响滑动切换日期和查看标题;
3)selectChange函数用于点击后把选中日期数据,如果要实现选中不同日期显示不同的日期列表,可在这里增加传参数调接口获取数据后替换timeList的数据。
import util from '../../utils/util.js'Page({ /** * 页面的初始数据 */ data: { tabsBoxHeight: 0, // 时间选择高度 titleHeight: 0, // 时间列表高度 clientHeight: 0, //可视区域高度 nowDay: {}, // 今天日期 selectDay: {}, // 选中时间 list: [], toView: 't1', // 用于定位滚动位置 timeList: [{ id: 1, time: '08:30-09:00', bookingNumber: 4 }, { id: 2, time: '09:00-09:30', bookingNumber: 10 }, { id: 3, time: '09:00-09:30', bookingNumber: 10 }, { id: 4, time: '09:00-09:30', bookingNumber: 10 }, { id: 5, time: '09:00-09:30', bookingNumber: 10 }, { id: 6, time: '09:00-09:30', bookingNumber: 10 }, { id: 7, time: '09:00-09:30', bookingNumber: 10 }] }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 计算时间高度 let that = this; this.nodeHeight('.tabs-box', 'tabsBoxHeight'); this.nodeHeight('.tr.title', 'titleHeight'); console.log(this.data) wx.getSystemInfo({ success: function (res) { console.log(res.windowHeight) that.setData({ // 可视区域高度 clientHeight: res.windowHeight }); } }); // 获取当前日期信息 let now = new Date(); let month = now.getMonth() + 1; month = month >= 10 ? month : '0' + month; let day = now.getDate(); day = day >= 10 ? day : '0' + day; let nowDay = { year: now.getFullYear(), month, day } let selectDay = nowDay; this.setData({ nowDay, selectDay }); this.dateInit(nowDay.year, nowDay.month); }, // 日历主体的渲染方法 dateInit(setYear, setMonth) { // 循环月数据 let now = new Date(setYear, setMonth - 1); // 当前月份的1号 let dayNum = new Date(setYear, setMonth, 0).getDate(); // 当前月有多少天 let list = []; let toView; for (let j = 0; j < dayNum; j++) { const now2 = new Date(now); now2.setDate(j + 1); let obj = {}; let day = now2.getDate(); day = day >= 10 ? day : '0' + day; // 补0 let month = now2.getMonth() + 1; month = month >= 10 ? month : '0' + month; // 补0 let year = now2.getFullYear(); let weekDay = now2.getDay(); let week = util.getWeeks(weekDay); let nowDay = this.data.nowDay; let isDisable; // 用于判断本月小于今天,下个月大于今天的日期不能选择 if (month == nowDay.month) { isDisable = (day < nowDay.day) ? true : false; } else { isDisable = (day >= nowDay.day) ? true : false; } // 获取今天的id前两个数字 if (day == nowDay.day) { toView = 't' + (j - 2); } obj = { id: 't' + j, day, month, year, weekDay, week, dateString: util.formatTime(now2), isWeekend: (weekDay === 0 || weekDay === 6) ? true : false, // 是否周末 isDisable }; list[j] = obj; } this.setData({ list, toView // 赋值需定位的位置 }) }, // 一天被点击时 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 } this.setData({ selectDay: selectDay }); }, // 获取节点高度 nodeHeight(nodeName, nodeHeight) { let that = this; var query = wx.createSelectorQuery(); query.select(nodeName).boundingClientRect(); query.exec(function (res) { switch (nodeHeight) { case 'tabsBoxHeight': that.setData({ tabsBoxHeight: res[0].height }); break; case 'titleHeight': that.setData({ titleHeight: res[0].height }); break; } }); }})