用最笨的方法记录工作中的一次数据处理
最近在做移动端的一个项目,项目中涉及到了一个日期选择的功能,如图所示,看上去貌似很简单,但是在做的过程中,发现难点主要是对于数据的组装。项目中用到的是Vant组件库,虽然其也有DatetimePicker时间选择器,但是我看了好久感觉还是有点不符合UI设计,尤其是到某一天的时候还要展示其是周几,很不好弄。所以想了想还是自己搞吧,借助Vant的Picker选择器,自己写了一个,最终的结果如图2,还有点差别,但是那已经不是什么大问题了,很简单!
UI稿
图2
第一步:确定数据结构
Vant的Picker选择器要求这种形式展现的数据结构是数组对象形式的,因此先确定了下面的这种数据结
[ { text: '2022年', type: 'year', shortName: 2022, children: [ { text: '01月', type: 'month', shortName: '1', children: [ { text: '01日(周一)', type: 'day', shortName: '1' } ] } ] } ];
第二步:处理数据
确定完数据结构后,然后就开始写代码了,具体的代码如const nowDate = new Date(); // 获取当前的日期const year = nowDate.getFullYear(); // 获取当前的年份const month = []; // 存储月份
for (let i = 1; i < 13; i++) { // 生成月份 month.push({ text: i < 10 ? '0' + `${i}月` : `${i}月` + '', type: 'month', shortName: i + '', children: dealDay(i) }); } // 处理日期(天和星期),因为每一年每个月份日期都是确定的(除2月外),所以大月是31天,小月是30天 function dealDay(month) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return dealDayWeek(year, month, 32); // 大月31 case 4: case 6: case 9: case 11: return dealDayWeek(year, month, 31); // 小月30 case 2: // 二月单独处理 return dealMonthDay(year); } } // 判断是闰年还是平年(闰年2月29,平年28) function dealMonthDay(year) { if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) { return dealDayWeek(year, 2, 30); } else { return dealDayWeek(year, 2, 29); } } // 根据日期获取星期几
year: 年份
month: 月份
total: 每个月的总天数
function dealDayWeek(year, month, total) { const weeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; const days = []; for (let i = 1; i < total; i++) {
// 根据传过来的每个月的天数循环和年、月组成新的数据,通过new Date('xxxx-xx-xx').getDay()的形式获取到星期几所对应的索引号,比如是0,则是星期天
const d = new Date(year + '-' + (month < 10 ? '0' + month : month) + '-' + (i < 10 ? '0' + i : i)).getDay();
const day = weeks[d]; // 获取星期几 days.push({ text: i < 10 ? '0' + i + `(${day})` : i + '' + `(${day})`, shortName: i + '', type: 'day' }); } // console.log(days) return days; }
// 组装完的结果
let dateTime = [{
text: year + '年',
shortName: nowDate.getFullYear() + '',
type: 'year',
children: month
}]
console.log(dateTime)
最终得到的结果如图片所示,大功告成(再继续优化一下就ok了)