相信有不少小伙伴和我一樣一提到日歷就腦殼疼溃斋,然后去網(wǎng)上搜索好用的日歷組件梗劫,如element-ui什么的,但是日歷畢竟是別人開發(fā)出來的枪萄, 和自己家ui設計出來的功能樣式畢竟不能100%相似猫妙,所以這個時候要么就去git上找一個相似的然后去修改代碼割坠,要么就只能自己開發(fā)一個了,所以我也是把我自己學到的日歷組件封裝思路分享給大家对妄;
雖然我知道日歷組件肯定已經(jīng)有很多人發(fā)過文章剪菱,寫過思路了拴签,但是我還是想寫一下。
準備工作
我是選擇弄一個新的腳手架去開發(fā)构灸,所以我是去vue-cli官網(wǎng)去拉取一個新的腳手架在本地喜颁,相信這個大家應該都會曹阔。
拉取成功之后npm serve 啟動;
然后我習慣一點用less寫css樣式赃份,所以我在裝一個less和less-loader,然后這個因人而異漓库;
開始
相信很多小伙伴和我一樣看到日歷之后不知道怎么下手渺蒿,如何能區(qū)分上下月和當前月呢彪薛,其實明白思路和原理之后就很簡單善延。
一個日歷有的是42天有的是35天,原因是6行或7行彼妻,7行展示的就比較全面豆茫;42天的優(yōu)點是能全部展示出上個月揩魂,當前月以及下個月,缺點是上個月和下個月占比較多牵舵,有些冗余畸颅,如果是35天看起來就會比較精簡妒峦,但有的月份就不能全部展示出來還是需要42天,這個也無傷大雅窥浪,我們就以42天為例笛丙;
首先我們需要看當前月的第一天是周幾胚鸯,5月的1號就是周三,那么就用42 - 2(這里注意如果是周日在第一個就是42 - 周幾坦冠,如果是周一在第一個就是42 - (周幾 - 1 )剩下的就是當前月和下個月的日期了辙浑。
我創(chuàng)建一個公共js里面放一些公共的方法方便在組件中調(diào)用;公共的js我就叫utils.js倦踢;
getYearMonthDay 就是utils里面的一個公共方法侠草,是為了方便獲取年月日辱挥;
const getYearMonthDay = (date) => {
let year = date.getFullYear();
let month = date.getMonth();
let day = date.getDate();
return {year, month, day};
};
computed: {
visibleCalendar: function () {
let calendatArr = [];
先得到當前的年边涕,月晤碘,日
let {year, month, day} = utils.getNewDate(utils.getDate(this.time.year, this.time.month, 1));
獲取當月的第一天 得到2019-5-1
let currentFirstDay = utils.getDate(year, month, 1);
獲取第一天是星期幾 得到 3
let weekDay = currentFirstDay.getDay();
用當月的第一天減去 周幾前面幾天 這樣就能得到上個月開始的天數(shù) (當前月1號是周三,那么周一就是上個月的最后兩天)
let startTime = currentFirstDay - (weekDay - 1) * 24 * 60 * 60 * 1000;
然后得到所有的日期
for (let i = 0; i < 42; i++) {
calendatArr.push({
date: new Date(startTime + i * 24 * 60 * 60 * 1000),
year: year,
month: month + 1,
day: new Date(startTime + i * 24 * 60 * 60 * 1000).getDate()
})
};
return calendatArr
}
}
然后dom結構去v-for這個數(shù)組,這樣就能得到一個初始的日歷了
但是這樣很丑奥吩,而且不能區(qū)分出哪一天是上個月哪一天是下個月哼蛆,所以我們需要給上下月去加一下樣式來區(qū)分當前月和上下月的區(qū)分
<ul class="calendar-view clear">
<li v-for="(item, index) in visibleCalendar"
:key="index"
class="date-view"
:class="[
{'notCurrentMonth-class': !isCurrentMonth(item.date)},
{currentDay: isCurrentDay(item.date)},
]"
@click="handleClickDay(item, index)"
>
<span class="date-day" >
{{item.day}}
</span>
</li>
</ul>
notCurrentMonth-class 是區(qū)分上下月的類名
currentDay 是判斷是否是今天的類名
判斷是否是當前月的方法,傳入每一天 用傳入的每一天去和當前年月做比較然后返回
isCurrentMonth (date) {
let {year: currentYear, month: currentMonth} = utils.getYearMonthDay(utils.getDate(this.time.year, this.time.month, 1));
let {year, month} = utils.getYearMonthDay(date);
return currentYear == year && currentMonth == month
}
判斷是否是當前天的方法 同理
isCurrentDay (date) {
let {year: currentYear, month: currentMonth, day: currentDay} = utils.getYearMonthDay(new Date());
let {year, month, day} = utils.getYearMonthDay(date);
return currentYear == year && currentMonth == month && currentDay == day;
}
然后給類名加一些自己喜歡的樣式就可以愉快的區(qū)分出當前月和上下月以及今天
現(xiàn)在就差左右切換和點擊今天回到當前月了霞赫,接下來就很簡單腮介,我們先寫兩個方法用來切換上下月
先去utils里面創(chuàng)建一個新的方法用來獲取當前幾月幾日
const getDate = (year, month, day) => {
return new Date(year, month, day);
}
在data () {
let {year, month, day} = utils.getYearMonthDay(new Date());
return {
yearMonth: {year, month, day},
}
}
// 上一個月 獲取當年月 用setMonth()去設置月份端衰,然后更新yearMonth
handlePrevMonth () {
let prevMonth = utils.getDate(this.yearMonth.year,this.yearMonth.month,1);
prevMonth.setMonth(prevMonth.getMonth() - 1);
this.yearMonth = utils.getYearMonthDay(prevMonth);
}
// 下一個月 獲取當年月 用setMonth()去設置月份叠洗,然后更新yearMonth
handleNextMonth () {
let nextMonth = utils.getDate(this.yearMonth.year,this.yearMonth.month,1);
nextMonth.setMonth(nextMonth.getMonth() + 1);
this.yearMonth = utils.getYearMonthDay(nextMonth);
}
// 點擊回到今天 同理
handleToday () {
this.yearMonth = utils.getYearMonthDay(new Date());
}
就這樣一個左右切換以及點擊回到今天的日歷就完成了,是不是非常非常的簡單旅东?
我把詳細的代碼上傳到了我的gitHub上面灭抑,在git上面我寫的更詳細一些,也提供了一些對外的點擊事件抵代,這樣在組件的外面可以調(diào)用里面的一些方法腾节,這樣用起來更方便,如果你覺得還不錯荤牍,可以去git上面給個星星或者是啥的案腺,感謝大家支持,如果有說的不對的地方康吵,歡迎指出劈榨,共同探討!