Vue實現(xiàn)日歷小插件
本文實例為大家分享了Vue實現(xiàn)日歷小插件的具體代碼,供大家參考,具體內容如下
先看下效果圖吧, 如下
源碼可見于我的github
實現(xiàn)關鍵點:
1.組件的復用以及父子組件傳值
很明顯每年每個月的月歷樣式(數據不一樣)是一致的,那么自然而然思路就是把每個月作為一個公用組件進行復用十二次,這樣就避免了多次重復的代碼。每個組件不一樣的地方在于年份和月份,而這兩個數據我們可以由父組件向子組件進行傳值來告訴子組件。關鍵代碼如下:
<template> <div class="wrap"> //months是一個包含十二個月名字的數組,用v-for對其進行循環(huán)渲染,并且把月份的index傳給子組件 <div v-for='(items, index) in months' v-if="index == monthIndex"> <month :monthName='items' :year='year' //年份傳給子組件,年份在mounted里面計算得出 :monthIndex='index' //月份傳給子組件 :day='today'//當日日期傳給子組件 :key='index' > </month> </div> </div> </template> //data部分 data () { return { monthIndex: 0, months:['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], year:-1, day:-1, } },
2.實現(xiàn)默認當日選中并且切換月份的時候其他月份不會有選中樣式
在父組件的mounted鉤子里面我們會計算當年當月當日,并傳給子組件,子組件的有個day屬性用于存儲父組件傳來的today的值,day屬性默認值為-1,父組件傳值過去之后會給day屬性重新賦值
//父組件 mounted () { let myDate = new Date(); this.monthIndex = myDate.getMonth(); this.year = myDate.getFullYear(); this.today = myDate.getDate() - 1; },
在子組件循環(huán)渲染每天的日期的時候會設置一個動態(tài)綁定樣式類似于一下代碼(實際代碼略微不一樣):
//index值為0-41 <div v-for="(item, index) in days" :key='index' class="dayIndex" @click='choose(index)' :class="{choose: day == index}"> //動態(tài)綁定樣式
當data中的屬性day的值和index的值相等的時候,就會給div添加一個choose的樣式,但是這樣有一個問題——那就是每個月的該index的div都會有這個class樣式。
解決辦法:在mounted里面做個判斷,如果為當月,則給data里面的day賦值,否則不做改動仍為-1,-1在循環(huán)渲染日期的時候沒有對應的index,所以不會產生選中樣式。
if (new Date().getMonth() == this.monthIndex) { this.chooseIndex = this.day + this.firstDayIndex; }
3.如何計算本月月歷中上個月多余的天數和下個月需要加進來的天數以及日期?、
這是該日歷里面比較復雜和關鍵的一點,我們可以看到每個月的日歷總共需要42天,除開本月天數,肯定還會包括上個月部分日期和下個月部分日期,所以該問題涉及以下多個因素:
1).本月1號前應該留給上個月多少天數
2).上個月最后的日期是不一樣的,有28 29 30 31
3).本月的天數和留給下個月的天數
4).非本月的日期需要置灰
這四個問題可以分別用下面的思路來解決:
問題1:計算本月的1號是周幾,如果是周一那么前面應當留1天給上個月(日歷從周日開始計算),如果是周二就應當留2天
每月1號可以用以下函數求得
new Date(year + '/' + monthIndex + '/' + '01').getDay();
問題2:可以在data里面建立一個hash表----monthLastDay(js對象),對應出每個月的天數,那么上個月的最后一天的日期就可以用monthLastDay[monthIndex - 1]求得,其中如果上個月是二月份要單獨判斷是否為閏年
monthLastDay:{ 0:31, 1:28, 2:31, 3:30, 4:31, 5:30, 6:31, 7:31, 8:30, 9:31, 10:30, 11:31 },
getMonthLastDay (year, month){ if (month != 1) { return this.monthLastDay[month]; } else { //this.leapyear是布爾值 它表示該年是否為閏年 if (this.leapyear) { return 29; } else { return 28; } } },
得到上個月最后一天的日期以及本月1號為周幾之后我們就可以知道需要填入的上個月日期有哪些了,可以往days數組(本月日歷渲染數據存儲數組)里push了。
問題3:這個問題就簡單很多了,因為本月日歷一共有42天,我們在一個i<42的for循環(huán)里面對數組days進行push,在push完上月日期和本月日期之后,把日期重置為1,繼續(xù)push到for循環(huán)結束就好了
//index為上個月最后一天的日期 lastDayNum為上個月剩余天數 generateDays (index, lastDayNum) { let temp = 1; //這個for循環(huán)是push上個月的剩余日期, for (let i = lastDayNum; i > 0; i--) { this.days.push([(index - i + 1).toString()]); } //index置1,開始push本月天數 index = 1; for (let i = 0; i < 42 - lastDayNum; i++) { //閏年二月 if (this.leapyear) { if (index <= 29) { this.days.push(index.toString()); } //非閏年月份 } else if (index <= this.monthLastDay[this.monthIndex]) { this.days.push(index.toString()); //這個else是push下個月的日期 } else { this.days.push([temp.toString()]); temp++; } index++; } },
問題4:在上面代碼中可以看到,在push非本月日期的時候,push進day數組的不是字符串而是一個數組[xxx.toString],這樣就可以區(qū)分本月和非本月日期,然后在v-if里面對值進行判斷添加class即可
<div v-for="(item, index) in days" :key='index' class="dayIndex" @click='choose(index)' :class="{choose: chooseIndex == index}"> //item為string 為本月日期 <div v-if="typeof(item) == 'string'"> {{item}} </div> //否則為非本月日期 添加class setGrey <div v-else class="setGrey"> {{item[0]}} </div> </div>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
vue使用v-model進行跨組件綁定的基本實現(xiàn)方法
這篇文章主要給大家介紹了關于vue使用v-model進行跨組件綁定的基本實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04vue-resource post數據時碰到Django csrf問題的解決
這篇文章主要介紹了vue-resource post數據時碰到Django csrf問題的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03vue-admin-box第一步npm?install時報錯的處理
這篇文章主要介紹了vue-admin-box第一步npm?install時報錯的處理方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10vue使用luckyexcel實現(xiàn)在線表格及導出導入方式
這篇文章主要介紹了vue使用luckyexcel實現(xiàn)在線表格及導出導入方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05搭建vue3項目以及按需引入element-ui框架組件全過程
element是基于vue.js框架開發(fā)的快速搭建前端的UI框架,下面這篇文章主要給大家介紹了關于搭建vue3項目以及按需引入element-ui框架組件的相關資料,文中通過圖文以及代碼介紹的非常詳細,需要的朋友可以參考下2024-02-02