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

相关文章
相关标签/搜索