设为首页 收藏本站
查看: 862|回复: 0

[新闻资讯] 小猿圈HTML5开发之利用Vue实现日历

[复制链接]
累计签到:3 天
连续签到:3 天
发表于 2019-6-27 17:08:31 | 显示全部楼层 |阅读模式
学习前端的小伙伴对于vue是不是都不陌生,那你有没有利用vue实现一些功能,今天小猿圈web前端讲师就分享一个利用Vue实现日历功能的知识点,有兴趣的话可以看一下。



实现关键点:
1.组件的复用以及父子组件传值
很明显每年每个月的月历样式(数据不一样)是一致的,那么自然而然思路就是把每个月作为一个公用组件进行复用十二次,这样就避免了多次重复的代码。每个组件不一样的地方在于年份和月份,而这两个数据我们可以由父组件向子组件进行传值来告诉子组件。关键代码如下:
<template>
<div class="wrap">
//months是一个包含十二个月名字的数组,用v-for对其进行循环渲染,并且把月份的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.实现默认当日选中并且切换月份的时候其他月份不会有选中样式
在父组件的mounted钩子里面我们会计算当年当月当日,并传给子组件,子组件的有个day属性用于存储父组件传来的today的值,day属性默认值为-1,父组件传值过去之后会给day属性重新赋值
//父组件
mounted () {
  let myDate = new Date();
  this.monthIndex = myDate.getMonth();
  this.year = myDate.getFullYear();
  this.today = myDate.getDate() - 1;
  },
在子组件循环渲染每天的日期的时候会设置一个动态绑定样式类似于一下代码(实际代码略微不一样):
//index值为0-41
<div v-for="(item, index) in days" :key='index'
class="dayIndex" @click='choose(index)'
:class="{choose: day == index}"> //动态绑定样式
当data中的属性day的值和index的值相等的时候,就会给div添加一个choose的样式,但是这样有一个问题——那就是每个月的该index的div都会有这个class样式。
解决办法:在mounted里面做个判断,如果为当月,则给data里面的day赋值,否则不做改动仍为-1,-1在循环渲染日期的时候没有对应的index,所以不会产生选中样式。
if (new Date().getMonth() == this.monthIndex) {
this.chooseIndex = this.day + this.firstDayIndex;
}
3.如何计算本月月历中上个月多余的天数和下个月需要加进来的天数以及日期?、
这是该日历里面比较复杂和关键的一点,我们可以看到每个月的日历总共需要42天,除开本月天数,肯定还会包括上个月部分日期和下个月部分日期,所以该问题涉及以下多个因素:
1).本月1号前应该留给上个月多少天数
2).上个月最后的日期是不一样的,有28293031
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循环里面对数组days进行push,在push完上月日期和本月日期之后,把日期重置为1,继续push到for循环结束就好了
//index为上个月最后一天的日期 lastDayNum为上个月剩余天数
generateDays (index, lastDayNum) {
let temp = 1;
//这个for循环是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],这样就可以区分本月和非本月日期,然后在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实现日历有了一定的了解,不过大家不要忘记点赞、收藏、转发呦,让更多和你一样有同样问题的同学得到帮助web前端自学②群:738735873,小猿圈为大家提供一个良好的学习平台。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-914517-1-1.html 上篇帖子: 小猿圈JS前端知识点整理总结 下篇帖子: 小猿圈Python开发之Django框架orM与自定义SQL语句混合事务
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表