element-ui 时间组件datePicker开始时间小于结束时间的校验,时分秒校验问题。
参考链接:https://blog.csdn.net/m0_38105640/article/details/120669974
一、安装引入element-ui
npm i element-ui -S
完整引入
在 main.js 中写入以下内容:
import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import App from './App.vue'; Vue.use(ElementUI); new Vue({ el: '#app', render: h => h(App) });
页面中使用:
<div> 开始时间: <el-date-picker v-model="startDateTime" type="datetime" placeholder="开始时间"> </el-date-picker> </div> <div> 结束时间: <el-date-picker v-model="endDateTime" type="datetime" placeholder="结束时间"> </el-date-picker> </div>
二、校验:
1.校验规则:开始和结束时间都是有时分秒的,结束时间要大于等于开始时间。
2.遇见问题:时分秒如何校验。
三、实现
选择开始时间之后,结束时间控件中,大于开始开始时间的日期设置为不可选状态。
注意两点:
1、:picker-options="pickerOptions" 这个属性用来设置日期禁用范围
2、日期比较时:endDateTime.slice(0, 10) 要截取日期进行比较,否则带上时间,当时间选择00:00:00和其他时间时,会出现开始时间和结束时间不能选择同一天的问题。
<template> <div class="testClass" style="text-align: left"> <el-form :model="postData" :rules="rules" ref="dataForm"> <el-form-item label="开始时间:" prop="start" style="display: inline-block"> <el-date-picker v-model="postData.startDateTime" type="datetime" popper-class="no-atTheMoment" value-format="yyyy-MM-dd HH:mm:ss" :picker-options="pickerOptionsStartDateTime" placeholder="开始时间" > </el-date-picker> </el-form-item> <el-form-item label="结束时间:" prop="end" style="display: inline-block"> <el-date-picker v-model="postData.endDateTime" type="datetime" placeholder="结束时间" value-format="yyyy-MM-dd HH:mm:ss" :picker-options="pickerOptionsEndDateTime" > </el-date-picker> </el-form-item> <div> 只能选择当前时刻以后的时间: <el-date-picker v-model="postData.expireDate" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" :picker-options="pickerOptions" placeholder="选择日期" /> </div> <el-button @click="sumitData"> 校验</el-button> </el-form> </div> </template> <script> export default { name: "datepicker", data() { var validateStartDatetime = (rule, value, callback) => { if (this.postData.endDateTime && this.postData.startDateTime) { if ( new Date(this.postData.startDateTime).getTime() > new Date(this.postData.endDateTime).getTime() ) { callback(new Error("开始时间需要小于结束时间!")); } else { callback(); } } else { callback(); } }; var validateEndDatetime = (rule, value, callback) => { if (this.postData.startDateTime && this.postData.endDateTime) { if ( new Date(this.postData.startDateTime).getTime() > new Date(this.postData.endDateTime).getTime() ) { callback(new Error("结束时间需要大于开始时间!")); } else { callback(); } } else { callback(); } }; return { postData: { startDateTime: "", endDateTime: "", expireDate: "", }, pickerOptionsStartDateTime: { disabledDate: (time) => { //设置禁用范围 if (this.postData.endDateTime) { return ( time.getTime() > new Date( this.postData.endDateTime.slice(0, 10) ).getTime() || time.getTime() > Date.now() //endDateTime.slice(0, 10) 截取日期进行比较,否则带上时间,当时间选择00:00:00和其他时间时,会出现开始时间和结束时间不能显示同一天的问题。 ); } else { return time.getTime() > Date.now(); } }, }, pickerOptionsEndDateTime: { disabledDate: (time) => { if (this.postData.startDateTime) { return ( time.getTime() < new Date( this.postData.startDateTime.slice(0, 10) ).getTime() - 8.64e7 || time.getTime() > Date.now() ); } else { return time.getTime() > Date.now(); } }, }, pickerOptions: { selectableRange: (() => { let data = new Date(); let hour = data.getHours(); let minute = data.getMinutes(); let second = data.getSeconds(); return [`${hour}:${minute}:${second} - 23:59:59`]; })(), disabledDate(time) { var date = new Date(); date.setFullYear(date.getFullYear() + 2); date.setDate(date.getDate() - 1); return ( time.getTime() < Date.now() - 8.64e7 || time.getTime() > date.getTime() ); }, }, rules: { start: [{ validator: validateStartDatetime, trigger: "change" }], end: [{ validator: validateEndDatetime, trigger: "change" }], }, }; }, methods: { sumitData() { const _this = this; _this.$refs["dataForm"].validate((valid) => { if (valid) { alert("成功"); } else { alert("失败"); } }); }, }, }; </script>
以上代码写完,但是发现时间也就是时分秒无法校验,也就是如果选择同一天日期,结束时间在时间上是可以选择小于开始时间的。经过下面的分析,忙着赶进度,我的解决办法就是给开始和结束时间又加了校验validate,因为时分秒的禁用状态不好加,但是又不能给后台传错误数据,所以在选完结束时间的change事件上加上校验,如果同一个日期,结束时间的时分秒选择了小于开始时间的时分秒,校验会提示错误,从而拦截。(没有真正解决问题,但是保证数据不错)如图:
这样做的理由:如果只是日期的校验,实现很简单,但是,加上时分秒之后,就希望对时分秒可也设置不可选状态。但是实现就出问题了,虽然时分秒也可以设置禁用状态,(通过timePiceker中的selectableRange属性),但是设置这个禁用状态的逻辑是依赖前面选择的开始时间日期的,举个例子:开始时间选择2021-10-03 02:02:02,结束时间的日期选择2021-10-03时,才需要将时间的控件02:02:02之前的时间设为禁用,当结束时间日期大于2021-10-03时,是不用对时间进行禁用设置的
听结束时间控件的日期选择时间,但是datetimePicker没有向外暴露这个事件。所以,官方文档没有这个解决的办法。我的思路是1.改源码,向外抛出点击日期的事件,或者日期那个input的change事件。但是改源码很麻烦,尤其是npm安装引用这种。2.就是操作dom监听点击日期的事件,或者日期那个input的change事件。也挺麻烦,毕竟原生js操作dom没有jquery那么方便。3.换时间插件。