Vue实现日历小插件


Posted in Javascript onJune 26, 2019

本文实例为大家分享了Vue实现日历小插件的具体代码,供大家参考,具体内容如下

先看下效果图吧, 如下

源码可见于我的github

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).上个月最后的日期是不一样的,有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循环里面对数组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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
20个非常棒的Jquery实用工具 国外文章
Jan 01 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
Sep 20 Javascript
Extjs4中tree的拖拽功能(可以两棵树之间拖拽) 简单实例
Dec 08 Javascript
jquery验证邮箱格式是否正确实例讲解
Nov 16 Javascript
jquery仿QQ登录账号选择下拉框效果
Mar 22 Javascript
Google 地图API Map()构造器详解
Aug 06 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
Nov 15 Javascript
Vue组件的使用教程详解
Jan 05 Javascript
Node.js应用设置安全的沙箱环境
Apr 23 Javascript
node.js使用免费的阿里云ip查询获取ip所在地【推荐】
Sep 03 Javascript
Vue数据驱动表单渲染,轻松搞定form表单
Jul 19 Javascript
详细聊聊浏览器是如何看闭包的
Nov 11 Javascript
微信小程序入口场景的问题集合与相关解决方法
Jun 26 #Javascript
Vue组件实现触底判断
Jun 26 #Javascript
vue-week-picker实现支持按周切换的日历
Jun 26 #Javascript
CKeditor4 字体颜色功能配置方法教程
Jun 26 #Javascript
Vue编写可显示周和月模式的日历 Vue自定义日历内容的显示
Jun 26 #Javascript
ES6 Symbol数据类型的应用实例分析
Jun 26 #Javascript
亲自动手实现vue日历控件
Jun 26 #Javascript
You might like
php调用mysql存储过程
2007/02/14 PHP
遭遇php的in_array低性能问题
2013/09/17 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
php 调用百度sms来发送短信的实现示例
2018/11/02 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
JQuery Tab选项卡效果代码改进版
2010/04/01 Javascript
Colortip基于jquery的信息提示框插件在IE6下面的显示问题修正方法
2010/12/06 Javascript
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
jQuery获取浏览器中的分辨率实现代码
2013/04/23 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
2013/08/30 Javascript
jquery中的on方法使用介绍
2013/12/29 Javascript
如何动态的导入js文件具体该怎么实现
2014/01/14 Javascript
JS遍历数组和对象的区别及递归遍历对象、数组、属性的方法详解
2016/06/14 Javascript
微信小程序 数据访问实例详解
2016/10/08 Javascript
基于Bootstrap的Java开发问题汇总(Spring MVC)
2017/01/15 Javascript
JavaScript实现时间表动态效果
2017/07/15 Javascript
template.js前端模板引擎使用详解
2017/10/10 Javascript
Bootstrap实现的表格合并单元格示例
2018/02/06 Javascript
p5.js入门教程之键盘交互
2018/03/19 Javascript
微信小程序实现之手势锁功能实例代码
2018/07/19 Javascript
electron实现qq快捷登录的方法示例
2018/10/22 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
详解在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入)
2020/07/11 Javascript
[56:35]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第一局
2016/03/06 DOTA
[55:26]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第一场 2月23日
2021/03/11 DOTA
python测试驱动开发实例
2014/10/08 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
对Tensorflow中Device实例的生成和管理详解
2020/02/04 Python
大学生专科学习生活的自我评价
2013/12/07 职场文书
酒吧总经理岗位职责
2013/12/10 职场文书
幼儿教师师德培训心得体会
2016/01/09 职场文书
解决Django transaction进行事务管理踩过的坑
2021/04/24 Python
一文搞懂python异常处理、模块与包
2021/06/26 Python
SpringCloud之@FeignClient()注解的使用方式
2021/09/25 Java/Android
对象析构函数__del__在Python中何时使用
2022/03/22 Python
利用Redis实现点赞功能的示例代码
2022/06/28 Redis