自己实现vue日历控制
日历控件在以前的项目中使用过。当时由于时间问题,在网上找到一个演示,然后重新开发。从那以后,我一直在考虑自己写一个日历控件。本文解释了日历数据的处理,去掉了月和日的判断,判断是否是闰年。
设计(用最常用的月历)
其实大家都很熟悉日历,所有的设计都是基于功能的,这是根本。日历的功能分为两部分。
日历表头:当前年度/月份。日历实体:当月的具体日期信息。日历正文行数:我们现在看到的日历基本上有6行,因为一个月最多有31天,假设当月的第一天是上个月最后一周的最后一天。如果是五行数据,只会显示29天,所以才会显示六行数据。功能点
日历的初始渲染日期是当月头左右滑动,日历数据需要显示对应月份的信息。点击日期本身进行相关的数据操作,录制操作内容可根据调用此设定日历的周数据,以周*、周日或周一开始。首先,思考日历的核心问题
如何获取当前日期的年和月
/* * *获取日历表头内容的格式:* * * * *年* *月* @ param {*}日期*/export const获取表头内容=函数(date) {let _ date=新日期(date) Return dateFormat(_date,' yyyy MM month')}如何获取当前月份要显示的42条数据(6*7),这42条数据是什么?
这个问题的核心是:当月显示的42个数据第一天是什么?
这个问题的解决应该从上面的设计开始。提到日历主题的行数,就说“假设当月的第一天是上月最后一周的最后一天”,那么42个数据中的第一个数据应该是基于当月的第一天,也就是第一天所在的周的第一天。
示例:2019年2月1日
2月的第一天,星期五,所以当月日历的第一天是2019-02-01-5
vardate=new date()date . setdate(date . getdate()-date . getday()1)//获取2019年1月28日当月的第一天。这里有什么问题?
date.getDate()的值是0-6(0是星期日,如果你的日历也把星期日放在日历的第一天,那就没有问题了,但是在中国,它把星期日放在最后一天),这意味着前面的实现也需要考虑日历的放置顺序,因为日历不同于普通的星期一到星期日或者星期日到星期一。因此,上述代码也取决于日历放电的顺序。
此处的放电顺序将是可由呼叫者控制的日历组件的第一个参数。我在这里的假设是将这个参数的传入值与date.getDay()匹配。
0:星期日1:星期一.5:周五6:周六,所以上面的公式是
设定日期。getdate ()-date。getday () x),但是如果这里加上x值后的日期大于当月的第一天,就需要从当前日期值中减去7天,所以没有必要解释这个原因。
/* * *获取当月日历的第一天* @ param { * } date */export const getfirst dayofcalendar=function(date,weeklabelundex){ let _ date=new date(date)_ date=new date(_ date . set date()-_ date . getday()-weeklabelundex))//如果当前日期晚于当月的第一天,则需要减去7天,如果(_ date){ _ date=new date(_ date)。setdate (_ date。getdate ()-7))} return _ date}。然后你就可以做好了,只需要在当前日期上加1,每次都得到第二天的日期。
如何设置左右切换月份
以上设计以今天为计算初始值。左右切换初始值如何设计?
第一反应是当前日期的月份加减1,这是不可行的,因为如果今天是31号,当下个月只有30号的时候,就会打到下个月,直接切换两个月。更不用说二月了,它的天数是不确定的。那么还有一个问题。
我的解决思路是:月份点击切换的时候,初始计算值设计为当前月的第一天。
/** * 以传入参数作为基准获取下个月的第一天日期* @ param { * } first dayofcurrentmonth */export const get first dayofcurrentmonth=function(first dayofcurrentmonth){ 0返回新日期(第一天当前月份。获取整年()、第一天或当月。getmonth()1,1)} /** *以传入参数作为基准获取上个月的第一天日期* @ param { * } first dayofcurrentmonth */export const get first dayofcurrentmonth=function(first dayofcurrentmonth){ 0返回新日期(第一天当前月份。获取整年()、第一天或当月。getmonth()-1,1)}左右切换月份数据传递方式(观察者模式)
因为对于日历组件本身来说,标题和身体是属于同一个父组件的同级组件,数据传递可以依赖于父组件进行传递,这里我使用的是观察者模式实现。
引入观察者模式代码:
/* *主题*内部创建了三个方法,内部维护了一个观察列表。*///构造函数导出const Subject=function(){ this。observers=new ObserverList()}//addobserver :调用内部维护的ObserverList的增加方法主题。原型。addobserver=function(observer){ this。观察员。add(observer)}//remove observer :调用内部维护的ObserverList的移除方法主题。原型。移除观察者=函数(观察者){ this。观察者。移除(在此。观察者。indexof(observer,0))} //notify:通知函数,用于通知观察者并且执行更新函数,更新是一个实现接口的方法,是一个通知的触发方法主题。原型。notify=function(context){ let observerCount=this。观察员。count()为(设I=0;我观察到了计数;{ this.observers.get(i).update(context)} }/* * ObserverList *内部维护了一个数组,4个方法用于数组的操作,这里相关的内容还是属于主题,因为ObserverList的存在是为了将科目和内部维护的观察者分离开来,清晰明了的作用*/函数Observer list(){ this。观察者列表=[]}观察者列表。原型。add=function(obj){返回这个。观察员名单。推送观察者列表。原型。count=function(){返回这个。观察员名单。长度}观察者列表。原型。get=function(index){ if(index-1)index this。观察员名单。length){返回这个。观察者列表[索引]} }观察者列表。原型。indexof=函数(obj,startIndex)提供更新接口,为想要得到通知消息的主体提供接口*/export const Observer=function(){ this。update=function(){//.}}CalendarBody观察者注册:
日历标题通知消息
组件设计以及结构
VueCalendar组件日历。vue calendarheader。vue lib主题。js Util。js索引。某视频剪辑软件当前效果
周一为第一天:
周日为第一天
开源代码库地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
版权声明:自己实现vue日历控制是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。