vue - 小日曆項目製做中的問題與解決思路

效果圖:css

 

項目難點:
1. 每月的日期數是不定的,攏共須要幾個格子?
按照教程的作法須要42個。因此遍歷數字42,獲得42個div作格子。
vue

 



2. 格子的排版怎麼作?
頂部的星期佈局使用的flex水平方向兩邊對齊並單項flex爲1佔滿空間。
下邊格子用了grid佈局(具體見源碼css)git

 



3. 本月一號是星期幾怎麼計算?
能夠利用Date對象提供的公式計算:
new Date(目標年份,目標月份 - 1,1).getDay();

4. 本月最大天數是幾怎麼計算?
能夠利用口訣計算:...
也能夠利用Date對象提供的公式計算:
new Date(目標年份,目標月份,0).getDate();

5. 本月一號從哪裏開始渲染?
由於全部格子是從1-42遍歷的。
github

 


咱們又獲得了本月一號是星期幾,因此咱們作一個判斷,當前格子的編號dayId是從1-42的。函數

判斷dayId大於beginDay(每個月1號是星期幾,0表示星期日,是第一個格子,6表示星期6是第7個格子。)就說明是本月開始日了,佈局

用公式if(dayId > beginDay)那麼渲染編號就不是dayId,而是dayId - beginDay。7-6就是1,8-6就是2,依次類推就有了1-31的日子。
flex

 


這裏判斷當前格子編號大於開始日、而且當前格子 - 開始往後,遍歷的數字不能超過本月最大數字。知足這倆條件的就是本月日曆數據。

this

 



6. 本月一號以前的幾天怎麼處理?(上個月那幾天灰色的怎麼計算、展現出來?)
有兩種計算方法,可是道理都是一個,當前格子的dayId是從1->beginDay的。而beginDay就是6之內的一個正數。spa

規律就是beginDay - dayId,依次就是七、六、五、四、三、二、1,dayId - beginDay就是-六、-五、-四、-三、-二、-一、0這樣。插件

而咱們又知道beginDay的前一天,也就是1號的前一天、上個月的最後一天的數字(好比31),31-正數 || 31 + 負數就都能求出來。


7. 從本月一號渲染到最大天數後、後邊怎麼計算?(下個月那幾天灰色的怎麼計算、展現出來?)
原理同上了,也是要判斷當前編號,若是當前編號dayId成了32,那就是大於本月最大天數(好比說31)了,那就從1開始計算。

難點是這個1編號乃至接下來的順序編號怎麼出。那就是當前dayId - 最大天數31 - 開始天數beginDay。

你想一想,beginDay是6,佔了前6個格子,最大天數是31,又佔了31個格子。這加起來就是37格。

當dayId編號是38的時候,38-37=1,下一個dayId是39,因而39-37=2,以此類推,就有了下個月的幾天。

 




以上三天,經過if判斷展現出了對應的三種span狀況。
8. 上個月&&下個月置灰的效果怎麼作?
咱們計算知道第一個span和第三個span都分別是上月和下月的日子,加上灰度類名便可。



9. 切換左右按鈕月份怎麼處理?切換到今天跳轉到當前日期

 


其實三個按鈕的原理同樣,都是切換按鈕,跳轉指定的年月(日是當前選中的,10-11問)。
就是要重置如下這幾個參數:

 


而這幾個參數初始化的時候處理過一遍,因此這裏封裝一下:

 


目的是渲染左上角這個日期。

 


並初始化數據this.nowYear等。
初始化的時候調用一下init、回到今天功能也是調用一下init,傳入當前日期便可。

 



上一個月和下一個月,分別傳入this.nowMonth --/++ 的數據,固然要作month的極值判斷

 



10. 點擊每一天切換類名並添加邊框樣式,此時調用函數傳參應該是啥?
個人初步理解,應該仍是當前dayId。而後咱們渲染的時候,判斷dayId和當前點擊變量重合就加一個類名錶示選中樣式。

:class="[(dayId - beginDay == nowDay && 'today'),(dayId == dayIndex && 'active')]"

today的判斷邏輯是:判斷當前實際渲染的日子(格子id"dayId" - 開始盒子編號「beginDay」) === 今天日期

 




active選中的判斷邏輯是:判斷當前格子編號"dayId" === 點擊div時重置的daiIndex的編號。

這裏這麼作有兩個問題:
一、today判斷的只有日期,第幾號,沒有判斷那一年那一月,我換個上個月的本日,today依舊生效
二、點擊上個月或下個月的灰色區域,會從新渲染表格,到時候保存的dayId和從新渲染後的dayId格子內的數字必定不一致,
所以修改以下:
首先today必須是"2019/06/06"這個字段徹底一致才能視作今天。
所以利用new Date().toLocaleDateString()獲得一個完整的日期字符串2019/5/28。而後每一個div上也渲染上data-str屬性,經過計算獲得當前格子所表明的時間"年/月/日"相同的串,
:data-str="getStr(三個span的哪個,當前月份, 當前格子的日期)"
由於三類span分別表明上月、本月、下月。因此也有可能會跨年,因此傳入第一個參數用於作判斷第二個參數的極值是12仍是1。
getStr內部邏輯以下:

 



最後判斷第一個問題:只有兩個串徹底相等纔是today。

 



這樣一來第二個問題:切換,也就好改了,拿着e.data.target.dataset時間串去init(傳參便可)

 



span @click="changeActive"
點擊的時候,去執行修改日期便可

 



11. 點擊下(上)個月那幾天灰色的切換到下(上)個月怎麼處理?
同上一條差很少

12. 當前選中本月31號,切換到上月沒有31號怎麼展現?
再次修改當前active的邏輯,修改變量名爲dayActive。
類名綁定邏輯爲:

 


初始話的時候,dayActive==當前日期

 


切換日期的時候,正則匹配到data-str綁定到span格子上的data屬性值的日期:

 




切換月份按鈕的時候,檢查切換前選中的是哪一天,而後判斷要切換的月份沒有這一天,(主要是31號的判斷,其餘1-28號都會有)就選中爲最大天。
this.maxDayNum是計算屬性很討巧。

 

源碼地址:github

相關文章
相關標籤/搜索