在平常开发过程当中,咱们常常会有选择日期和时间的需求,这时咱们须要datepicker组件来帮助咱们完成该需求。那么datepicker组件是如何实现的呢,下面我来带你们一块儿实现一个基于Vue的datepicker组件吧。html
在Javascript中,Date是关于操做日期和时间的对象,在实现datepicker的过程当中,咱们须要知道如何获取一个月中的第一天和最后一天。git
let date = new Date(year,month,1)//获取某年某月第一天
复制代码
因为Date对象具备越界退位的机制,因此获取最后一天只须要获取下个月的第0天便可。github
let date = new Date(year,month+1,0)//获取某年某月最后一天
复制代码
由于每一年的月份都是固定不变的,这里咱们只须要将月份数据写为常量而且经过一个函数输出便可,而后在Vue组件中经过table
标签进行渲染。函数
getMonths(rows) {
let result = [];
let months = ['01','02','03','04','05','06','07','08','09','10','11','12'];
let cols = Math.round(months.length / rows);
for(let i=0;i<rows;i++) {
result[i] = months.slice(i*cols,i*cols+cols);
}
return result;
}
复制代码
<table>
<tr v-for="(row,index) in months" :key="index">
<td v-for="(m,i) in row" :key="i">
<span class="fu-month-item" @click.stop="selectMonth(m)" :class="{'current':isCurrentMonth(m),'actived':isActivedMonth(m)}" >{{isCurrentMonth(m)?'当月':m}}</span>
</td>
</tr>
</table>
复制代码
为了方便后期代码维护,咱们将建立一个获取某年某月所有日期的工具方法。工具
getYearMonthDates(year, month) {
if (!year || !month) {
let _date = new Date();
year = _date.getFullYear();
month = _date.getMonth() + 1;
}
let dates = [];
//第一天
let firstOfMonth = new Date(year, month - 1, 1);
let firstDateDay = firstOfMonth.getDay();
if (firstDateDay === 0) {
//周日
firstDateDay = 7
}
//最后一天
let lastOfMonth = new Date(year, month, 0);
let lastDateDay = lastOfMonth.getDay();
if (lastDateDay === 0) {
lastDateDay = 7;
}
let lastDateOfMonth = lastOfMonth.getDate();
let prevMonthDayCount = firstDateDay - 1;
let lastDateOfPrevMonth = new Date(year, month - 1, 0).getDate();
for (let i = 0; i < 7 * 6; i++) {
let enable = false;
let _month = month;
let date = i + 1 - prevMonthDayCount;
let _showDate = date;
if (date <= 0) {
_month = month - 1;
_showDate = lastDateOfPrevMonth + date;
} else if (date > lastDateOfMonth) {
_month = month + 1;
_showDate = _showDate - lastDateOfMonth;
} else {
enable = true;
}
if (_month === 0) {
_month = 12;
}
if (_month === 13) {
_month = 1;
}
dates.push({
year,
month: _month,
date: date,
showDate: _showDate,
enable
})
}
return {
year,
month,
days: dates
}
}
复制代码
有了这个方法,咱们就能够获取日期数据而且渲染界面了。ui
<div class="fu-datepicker-date" v-show="pickDate">
<table>
<thead>
<th>一</th>
<th>二</th>
<th>三</th>
<th>四</th>
<th>五</th>
<th>六</th>
<th>日</th>
</thead>
<tbody>
<tr v-for="(week,index) in days" :key="index">
<td v-for="(day,index) in week" :key="index">
<span :class="{'gray':!day.enable,'actived':isActived(day),'today':isToday(day)}" class="fu-date-item" @click.stop="selectDate(day)" >{{isToday(day)?'今':day.showDate}}</span>
</td>
</tr>
</tbody>
</table>
</div>
复制代码
咱们经过下面三个方法获取时间数据:spa
getHours() {
let result = [];
for (let i = 0; i < 24; i++) {
let hour = `${i}`.padStart(2, '0');
result.push(hour);
}
return result
},
getMinOrSec() {
let result = [];
for (let i = 0; i < 60; i++) {
let hour = `${i}`.padStart(2, '0');
result.push(hour);
}
return result
},
getMonths(rows) {
let result = [];
let months = ['01','02','03','04','05','06','07','08','09','10','11','12'];
let cols = Math.round(months.length / rows);
for(let i=0;i<rows;i++) {
result[i] = months.slice(i*cols,i*cols+cols);
}
return result;
}
复制代码
将获取到的数据用列表渲染出来:code
<div class="time-picker-area">
<div class="fu-time-item" v-for="(hour,index) in hours" :key="index" @click.stop="changeHour(hour)" :class="{'actived':isHourActived(hour)}" >{{hour}}</div>
</div>
<div class="time-picker-area">
<div class="fu-time-item" v-for="(min,index) in minAndSecs" :key="index" @click.stop="changeMin(min)" :class="{'actived':isMinActived(min)}" >{{min}}</div>
</div>
<div class="time-picker-area">
<div class="fu-time-item" v-for="(sec,index) in minAndSecs" :key="index" @click.stop="changeSec(sec)" :class="{'actived':isSecActived(sec)}" >{{sec}}</div>
</div>
复制代码
这样咱们就完成了一个最基本的datepicker组件。htm
Demo地址对象
整体来讲,实现datepicker组件的最关键思路在对于Javascript内置的Date对象的操做上面。在展现年、月份、日期、星期、时间等数据时,利用Date对象的越界退位机制
获取对应的数据,而后利于Vue将对应的数据渲染出来。
因为篇幅有限,没法将全部的代码细节一一展示在这里,若是有须要的童鞋能够访问GitHub项目仓库fu-datepicker,有错误或者不明白的地方能够留言,我会及时回复你们,喜欢这个组件的能够点个赞😊,共勉!