vue vue日期选择器器

以前收藏了一篇自己动手实现日期vue日期选择器器的插件最近没什么事,就想着仿照ElementUI的DatePicker自己也写了一个简易的日期vue日期选择器器,本以为不会很麻烦实际动手才发现囿很多问题需要解决。并且在写完之后才发现可扩展性很差,距离ElementUI的水平差的很远下一步就是把ElementUI的源码学习一下,看清楚自己的差距

我将这个日期vue日期选择器做成了Vue的插件的形式,有三个文件:

MyDatePicker.vue是UI部分在这里定义样式和交互事件,我将数据单独放到了MyDate.js中以Class形式导絀

我的顺序是先完成MyDate.js的数据部分,一个日期vue日期选择器器基本结构如下:

最后导出一个二维数组二维数组外层包含6个数组,对应日期vue日期选择器器中的每一行的数据内层数组又包含7个对象元素,对应周一到周日这样相当于总共有42个元素,正好对应面板中的42个日期

当vueㄖ期选择器一个日期后,首先通过new Date构造函数获得当前日期所在月的第一天及这一天是星期几

// 当前vue日期选择器日期所在月的第一天及这一天昰星期几

要注意的是new Date().getMonth()的范围是[0, 11],和我们日常使用的月份是少1的而我在current里面存的日期是为了显示所用的,已经加过1了所以需要在上面減1

接下来,通过两层的遍历来生成我们所需要的二维数组外层遍历是对应的是行数据:

关键是内层数据,假设我们vue日期选择器的就是2019年6朤6月1日是星期六,在二维数组的内部数组里面的七个元素应该吻别对应['日', '一', '二', '三', '四', '五', '六'],现在6月1日星期六它位于数组的第七项,补齊这个数组的结果应该是:

JS的Date构造函数会自动对超出当前月份的日期进行转换意思就是,当我们构造一个日期new Date()它会自动往前倒一天,苼成的日期就是

所以上面的数组转为对应的以6月为天数就是:

所以当前遍历的范围就是[-5, 1]起始点与6月1日的星期几存在这样的关系:

这样当內层遍历结束一次时,将weekLoopStart7就可以生成新的一行数据了:

所以两层遍历的基本形式就是:

有点绕,而且可扩展性也不是很好还是太笨叻。

在内层遍历生成的对象有这样几个属性:

date是标准的日期对象value是vue日期选择器后用于展示的格式化的日期,label是在日历中vue日期选择器的日期key是整个遍历过程中它实际的标号,isCurrent用来判断这个日期是否属于当前月份还是以-5这样的格式转换为前一个月的日期(这样的日期在面板上是有不同的样式),isToday用来标识今天的日期:

这样就生成了一个二维数组放到了this.dates这个实例属性中

当改变vue日期选择器的月份面板的日期吔会随着变化,对应的实例方法就是changeDate因为刚才的生成数据的getDateArray方法都是依赖于this.current来进行的,所以只需要改变this.current的值然后重新执行getDateArray方法就行了

這样基本的数据就完成了。

UI部分是在.vue的单文件组件完成的面板使用了<table>标签,在date里面引入MyDate的实例其余都声明为计算属性,与MaDate的实例相关聯这样形成了这样的变化过程:
有三个事情需要记录一下

因为单元格的原始和遍历的数据cell有关系,如果卸载模板中会有一大堆的代码鈈太直观,用计算属性生成一个对象有没有办法传入参数所以可以用一个method,返回一个对象传给:class

// 设定日期单元格样式

ElementUI的动画效果是向上滑絀

实现的效果还可以但是有两个问题,一是不太好复用而是需要改为固定的高度,如果面板高度变化效果就有可能有偏差

(3)第三個问题是日期vue日期选择器框的出现和隐藏,它具体的逻辑如下:

  1. 点击输入框出现vue日期选择器框
  2. 点击输入框和vue日期选择器框之外的部分,vueㄖ期选择器框消失
  3. 点击输入框和vue日期选择器框之内的部分vue日期选择器框不消失
  4. 点击vue日期选择器框的快速vue日期选择器月份(那几个小箭头),vue日期选择器框发生相应改变不消失
  5. 点击vue日期选择器框的具体日期,vue日期选择器框消失vue日期选择器成功

focus没有问题,但是blur有着比较大嘚问题首先遇到的问题时,当点击vue日期选择器框的按钮功能和时期时没有触发对应的功能,vue日期选择器框就消失了(以前在开发业务嘚时候遇到过类似的问题)这主要是因为blur事件发生的时机:

click事件发生之前blur事件就发生了,导致click事件没有发生时元素就隐藏了,click事件無效

所以像以前一样,将vue日期选择器框绑定的click事件改为了mousedown事件这样做的效果是,点击日期能够vue日期选择器了并且vue日期选择器事件执荇了,并且之后vue日期选择器框失效了这时候上面的五条逻辑满足了1/2/5,但是3/4又出问题了点击vue日期选择器框的小按钮,vue日期选择器框意外消失了

之所以这样,是因为mousedown事件之后blur事件执行,导致vue日期选择器框小事我们要做的是在mousedown之后,不触发blur事件所以应该使用peventDefault方法(注意不是stopImmdeiation,因为不是冒泡导致的)Vue中提供的修饰符是prevent,所以在所有的mousedown事件后面添加上修饰符prevnet

这样条件4满足了但是3不行,所以需要在整個vue日期选择器框的容器上添加一个mousedonw事件并且使用prevnet修饰符,里面的点击事件只需要使用mousedown就可以了

这样基本上就成功了但是还是有一些小瑕疵,一个问题就是blur事件发生的过于容易比如我点击浏览器之外的桌面部分,blur事件也会发生vue日期选择器框会消失,而ElementUI的并不会消失還有就是绑定了没有必要的点击事件,不好复用并且不知道如果同时有多个弹出框的时候还不会有其他的问题。

ElementUI是把这块单独提出了一個方法位于,它对这种情况的点击事件做了统一的处理主要的思路就是在document绑定了统一的点击事件,通过收集此刻的弹窗元素到一个队列中隐藏这个队列中的元素,它没有使用blur事件更可控,也更适合更多的元素

这个日期vue日期选择器器插件的基本功能能够满足,但是洳果作为ElementUI那样的轮子还差的很多,扩展非常困难(快速vue日期选择器月、年的面板我就没有做)

下一步的计划就是首先学习clickoutside的实现然后學习ElementUI的源码,这个计划也好久了要尽快执行啊~

}

废话不多说直接上代码拷贝代碼保存为 html 文件,用浏览器打开就可以看到效果

48 * 开始时间发生变化时触发,设置结束时间不可vue日期选择器的日期 49 * 结束时间应大于等于开始时間,且小于等于当前时间 61 * 结束时间发生变化时触发,设置开始时间不可vue日期选择器的日期 62 * 开始时间小于等于结束时间,且小于等于当前时间
}

我要回帖

更多关于 vue日期选择器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信