时间:2021-05-26
本文实例为大家分享了Vue实现日历小插件的具体代码,供大家参考,具体内容如下
先看下效果图吧, 如下
源码可见于我的github
实现关键点:
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>以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
最近用vue在做一个项目,github用上找了一个日历插件,intall到了本项目中,配好以后发现插件的样式风格和项目总体风格相差较大,所以就像这个改一下插件风
前言最近老牌日历插件fullcalendar更新了v4版本,而且添加了Vue支持,所以用最新的fullcalendarv4制作一个完整日历体验一下,效果图:安装
很多朋友的IOS7设备越狱都在通知栏里增加日历、农历的显示,那么如何实现IOS7通知栏显示日历及农历?是插件还是设置问题呢?下面小编就给大家演示一下&ldquo
本文实例为大家分享了vue-week-picker实现按周切换的日历的具体代码,供大家参考,具体内容如下vue-week-picker安装npminstallv
微信小程序日历选择器插件点击日历日期可以获取到年月日,具体内容如下wxml《{{cur_year||"--"}}年{{cur_month||"--"}}月》{{