相信有不少小夥伴和我一樣一提到月曆就腦殼疼,然後去網上搜尋好用的月曆元件,如element-ui什麼的,但是月曆畢竟是别人開發出來的, 和自己家ui設計出來的功能樣式畢竟不能100%相似,是以這個時候要麼就去git上找一個相似的然後去修改代碼,要麼就隻能自己開發一個了,是以我也是把我自己學到的月曆元件封裝思路分享給大家;
雖然我知道月曆元件肯定已經有很多人發過文章,寫過思路了,但是我還是想寫一下。
準備工作
我是選擇弄一個新的腳手架去開發,是以我是去vue-cli官網去拉取一個新的腳手架在本地,相信這個大家應該都會。 拉取成功之後npm serve 啟動;
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iZmVDN1Y2NiVjYjNjY5MWN3ITO3QTZ4Q2YjZzMmBDM48CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
image.png
然後我習慣一點用less寫css樣式,是以我在裝一個less和less-loader,然後這個因人而異;
開始
image.png
相信很多小夥伴和我一樣看到月曆之後不知道怎麼下手,如何能區分上下月和目前月呢,其實明白思路和原理之後就很簡單。
一個月曆有的是42天有的是35天,原因是6行或7行,7行展示的就比較全面;42天的優點是能全部展示出上個月,目前月以及下個月,缺點是上個月和下個月占比較多,有些備援,如果是35天看起來就會比較精簡,但有的月份就不能全部展示出來還是需要42天,這個也無傷大雅,我們就以42天為例;
首先我們需要看目前月的第一天是周幾,5月的1号就是周三,那麼就用42 - 2(這裡注意如果是周日在第一個就是42 - 周幾,如果是周一在第一個就是42 - (周幾 - 1 )剩下的就是目前月和下個月的日期了。
我建立一個公共js裡面放一些公共的方法友善在元件中調用;公共的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(); 用當月的第一天減去 周幾前面幾天 這樣就能得到上個月開始的天數 (目前月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這個數組,這樣就能得到一個初始的月曆了
image.png
但是這樣很醜,而且不能區分出哪一天是上個月哪一天是下個月,是以我們需要給上下月去加一下樣式來區分目前月和上下月的區分
{{item.day}} notCurrentMonth-class 是區分上下月的類名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;}
然後給類名加一些自己喜歡的樣式就可以愉快的區分出目前月和上下月以及今天
image.png
現在就差左右切換和點選今天回到目前月了,接下來就很簡單,我們先寫兩個方法用來切換上下月
先去utils裡面建立一個新的方法用來擷取目前幾月幾日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 月曆位址:https://github.com/xiangnideye/vue-date-picker
我把詳細的代碼上傳到了我的gitHub上面,在git上面我寫的更詳細一些,也提供了一些對外的點選事件,這樣在元件的外面可以調用裡面的一些方法,這樣用起來更友善,如果你覺得還不錯,可以去git上面給個星星或者是啥的,感謝大家支援,如果有說的不對的地方,歡迎指出,共同探讨!
作者:Alawaysonl_c839
連結:https://www.jianshu.com/p/d8ce25e9badb