需求描述
最近在做有关element的时间选择器timePicker时,遇到这样一个需求:首先我需要的是选择时间段 格式为'HH:mm'
,在它之前还有一个datePicker日期选择器,日期需要只能选择当天及以后的日期,格式为'yyyy-MM-dd'
;当我选择当天时,时间段开始时间为当前时间,之前的时间禁用,当不为当天时,开始时间从0点开始,且结束时间不得在开始时间之前。
整理一下,大致分为以下几个功能点:
- 日期选择器datePicker实现只能选择当天及之后的日期
- 时间选择器timePicker实现根据datePicker选择的日期动态变化开始时间且结束时间要大于开始时间
解决
饭要一口一口吃,路要一步一步走。我们逐个解决上述需求!
日期选择器datePicker实现只能选择当天及之后的日期
我采用的是默认日期选择器
图中圈中的话便是我们的解决方案,通过使用picker-options
对象中的disabledDate
属性就可以实现禁用我们相要禁用的日期啦~ 代码及展示图如下:
<template>
<el-date-picker
v-model="ruleForm.inspectionDate" // 日期选择器绑定值,最终选择的值
type="date"
:picker-options="pickerOptions0"
format="yyyy-MM-dd" // 规定日期格式,与下一行并用不会出错
value-format="yyyy-MM-dd"
placeholder="选择日期"
@change="controllStartTime" // 绑定一个change事件,后续有关时间选择器会用到,此处可忽略
/>
</template>
<script>
export default {
data() {
return {
// 限制时间选择器只能选择当天及以后的日期
pickerOptions0: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7// 如果没有后面的-8.64e7就是不可以选择今天的
}
}
}
}
}
</script>
时间选择器timePicker实现根据datePicker选择的日期动态变化开始时间
首先说明一下,我最开始想要通过下图中的timePicker格式来实现这个需求,但是使用了各种办法还是失败了(禁用不了),经过很多尝试,也未能通过这个格式的组件实现功能(后续有时间再研究一下,如果成功,会更新此文章🐷)。
PS:此处有更新:最新的时间段禁用方法请看此连接(依然是两个组件🐷)时间选择器实现精确到时分禁用多个时间段并能动态更新禁用时间段,超级详细(附完整代码及文件)
但是需求就摆在那里,不解决是不行的,所以,我换了一种思路,我采用两个如下图所示格式的timePicker组合实现。
对这两个timePicker进行布局样式设计,最终效果图如下:
既然结构已经设计好,接下来就要实现时间段根据选择的日期来动态变化开始时间了。我们需要的效果是这样的:点击巡视日期日期选择器,选择当天时,巡视时间段开始时间则从当前时间开始,格式为'HH:ss'
;当选择当天之后的日期时,开始时间从0点开始。这时候,就要用到前面所说的给datePicker绑定一个change事件,当日期变化时,触发change事件。我们需要在绑定的事件方法中实现代码逻辑,完成上述功能。代码如下:
// 只是表单的部分代码
<template>
<div>
<el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="150px" class="box-card">
<el-form-item label="巡视日期" required>
<el-col :span="11">
<el-form-item prop="inspectionDate">
<el-date-picker
v-model="ruleForm.inspectionDate"
type="date"
:picker-options="pickerOptions0"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="选择巡视日期"
class="selectDate"
@change="controllStartTime"
/>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="巡视时间段" class="timeRange" required>
<el-col :span="11">
<el-form-item prop="mySelectTimeRange">
<el-time-picker
v-model="startTimeRange" // 绑定最终选择的值
class="timePicker"
format="HH:mm"
:picker-options="{
selectableRange: `${changeStartTime} - 23:59:59`, // 含有变量或函数时,使用``反引号包裹;这里只是表示时间范围
format:'HH:mm' // 规定时间格式,与外层必须同时存在,否则会报错(格式不对)
}"
placeholder="开始时间"
@change="controllEndTime" // 与日期选择器的用法同理,此处绑定change事件监听结束时间变化
/>
<span style="padding:0 5px;">-</span>
<el-time-picker
v-model="endTimeRange"
class="timePicker"
format="HH:mm"
:picker-options="{
selectableRange: `${changeEndTime} - 23:59:59`,
format:'HH:mm'
}"
placeholder="结束时间"
/>
</el-form-item>
</el-col>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
// 初始化定义时间
startTimeRange: new Date(),
endTimeRange: new Date(),
changeStartTime: new Date(),
changeEndTime: new Date()
}
},
created() {
this.handleTime()
},
mounted() {
this.handleTime()
},
methods: {
// 获取开始时间变化
controllStartTime() {
this.handleTime()
},
// 操控禁用时间
handleTime() {
var tempTime = new Date()
const toStringTempTime = this.formatDate(tempTime, 'yyyy-MM-dd') // 将获取到的当前时间转化为年-月-日字符串
const formSelectedTime = this.ruleForm.inspectionDate // 日期选择器的时间,字符串型
if (formSelectedTime === toStringTempTime) { // 当前日期等于时间选择器选中的日期
this.changeStartTime = new Date()
this.startTimeRange = this.changeStartTime // 时间段开始时间设置为当前时间
} else {
this.changeStartTime = new Date(new Date(new Date().toLocaleDateString()).getTime() - 24 * 60 * 60 * 1000) // 变为0点
this.startTimeRange = this.changeStartTime // 时间段开始时间为0点
}
this.controllEndTime() // 调用此函数,控制结束时间
},
// 获取结束时间变化
controllEndTime() {
if (this.startTimeRange !== '' && this.startTimeRange !== null) { // 当开始时间不为空;不加判断当清除开始时间时控制台会报错
this.changeEndTime = new Date(new Date(this.startTimeRange.getTime() + 1 * 60 * 1000)) // 选择开始时间后使结束时间永远比开始时间多1分钟,此处可根据需求自行设置
this.endTimeRange = this.changeEndTime
}
},
// 根据type返回不同格式的时间字符串
// 补充一下:时间段的开始时间和结束时间最终也需调用此方法转换格式,因为一般后端要求接收`HH:ss`格式的字符串,日期同样如此。
formatDate(date, type) {
var now = date
var newTime
if (type === 'yyyy-MM-dd') {
var year = now.getFullYear()
var month = now.getMonth() + 1
month = month < 10 ? ('0' + month) : month
var day = now.getDate()
day = day < 10 ? ('0' + day) : day
newTime = year + '-' + month + '-' + day
}
if (type === 'HH:ss') {
var getHour = now.getHours()
getHour = getHour < 10 ? ('0' + getHour) : getHour
var minutes = now.getMinutes()
minutes = minutes < 10 ? ('0' + minutes) : minutes
newTime = getHour + ':' + minutes
}
return newTime
}
}
}
</script>
到这里,我们就完成了时间段的开始时间随日期的变化而变化啦,同时,也实现了结束时间永远大于开始时间。效果如下:
当我们选择开始时间后,结束时间会自动变化为开始时间+1分钟,在当天时,开始时间无法选择将当前时间之前的时间,不在当天时,开始时间可选全天任意时间。结束时间无法选择开始时间之前的时间。演示动图如下(附gif转换在线地址文件转换器):
小结
有关timePicker时间段的问题,当时在做项目时困扰了我很久,可能是官方文档也并未给出相关属性使用,所以只能用另一种思路解决了。希望我的做法能对各位大佬有所帮助😄
最后,如果文中哪里有问题的话欢迎各位大佬指出!撰写不易,给颗小红心吧😜