前言
日历是我们开发过程中经常会使用到的一个功能,po主在开发小程序的过程中就遇到一个场景需要使用日历组件。首先上网搜索一番,但是没有找到合适自己的,于是便决定自己写一款小程序日历组件。
先上效果图:
效果体验:
功能分析
这款日历组件主要是提供日期选择功能。首先是年月日,然后是时分秒。并且提供配置开始时间和结束时间设置,以及周末是否可选的设置项。
总体来说分为两大部分:
- 年月日选择功能
- 时分秒选择功能
实现分析
年月日选择
构造数据结构
要实现年月日选择功能,首先我们使用下面代码中的 setMonthData 函数构造一个 7 * 6 的数据结构, 这个数据结构包含当月,以及部分上月和下月的天数。在构造的时候通过 isValidDay 函数判断当天是否可以选择,然后加上 valid 一个标识,以便在渲染的时候用于显示和点击判断。
构造完成的数据结构如下:
{ date: date, // 当天日期 dateStr: date.toString(), // 当天日期的字符串,渲染时候比较使用,由于小程序的wxml的语法限制,这里把日期转化成字符串进行比较 day: date.getDate(), // 当天日期的天数 valid: valid, // 当天日期是否是可以选择的 currentMonth: false // 当天日期是否是本月的日期 }
setMonthData 和 isValidDay 函数代码:
// 根据条件判断当天日期是否有效 isValidDay(date) { let {startDate, endDate, needWeek} = this.data; let valid = false; if (startDate && endDate) { // 开始日期和结束日期都存在 if (date >= startDate && date < endDate) { valid = true; } } else if (startDate && !endDate) { // 开始日期存在结束日期不存在 if (date >= startDate) { valid = true; } } else if (!startDate && endDate) { // 开始日期不存在结束日期存在 if (date < endDate) { valid = true; } } else { valid = true; } if (!needWeek) { let weekDay = date.getDay(); if (weekDay === 0 || weekDay === 6) { valid = false; } } return valid; } // 根据传入的日期构造数据 setMonthData() { const currentDate = this.data.currentDate; let year = currentDate.getFullYear(), month = currentDate.getMonth(); // 当月所有天数的数据结构 let currentData = []; // 获取当月1号的星期0~6 let firstDayWeek = new Date(year, month, 1).getDay(); // 天数, 用来标识当前是本月中的哪一天 let dayIndex = 0; // 第1行 let firstCol = []; for (let i = 0; i < 7; i++) { if (i < firstDayWeek) { let date = new Date(year, month, dayIndex - (firstDayWeek - i) + 1); let valid = this.isValidDay(date); firstCol.push({ date: date, dateStr: date.toString(), day: date.getDate(), valid: valid, currentMonth: false }) } else { dayIndex += 1; let date = new Date(year, month, dayIndex); let valid = this.isValidDay(date); firstCol.push({ date: date, dateStr: date.toString(), day: dayIndex, valid: valid, currentMonth: true