一 . 效果图
二 . 步骤
1.创建时间框的组件
组件中的代码:
<template>
<div class="com-time-range">
<el-date-picker
v-model="start_time"
class="com-time-range-item"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetime"
prefix-icon="el-icon-date"
:picker-options="startPickerOptions"
@change="startTimeChange"
:placeholder="startPlaceholder"
:default-value="defaultStartValue"
popper-class="common-time-range-popper"
/>
<span>-</span>
<el-date-picker
v-model="end_time"
class="com-time-range-item"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetime"
prefix-icon="el-icon-date"
:picker-options="endPickerOptions"
@change="endTimeChange"
:default-value="defaultEndValue"
:placeholder="endPlaceholder"
popper-class="common-time-range-popper"
/>
</div>
</template>
<script>
// 获取选择天数已经过去的毫秒数
import { parseTime } from '@/utils'
// 通用时间选择框
export default {
name: "ComTimeRange",
props: {
// 开始时间的placeholder
startPlaceholder: {
type: String,
default() {
return '请选择'
}
},
// 结束时间的placeholder
endPlaceholder: {
type: String,
default() {
return '请选择'
}
},
// 双向绑定的值
value: {
type: [String, Array],
default() {
return []
}
},
// 可选时间范围,单位-秒,默认24h
timeRange: {
type: [String, Number],
default: 86400
},
// 是否启用时间范围禁用的校验
useTimeRange: {
type: Boolean,
default: false
}
},
watch: {
value: {
// deep: true,
handler(val) {
this.start_time = val[0] || ''
this.end_time = val[1] || ''
}
},
start_time: {
handler(val) {
const { timeRange, useTimeRange } = this
this.endPickerOptions = {
disabledDate(time) {
// TODO 如果没有值,需要恢复可选择的状态
const max = new Date(val).getTime() - 8.64e7 + 1
// 符合条件的时间
time = time.getTime()
const time1 = (new Date(val).getTime() + timeRange * 1000)
const min = (useTimeRange && val) ? (Date.now() < time1 ? Date.now() : time1) : Date.now()
return time < max || time > min
}
}
}
},
end_time: {
handler(val) {
const { timeRange, useTimeRange } = this
this.startPickerOptions = {
disabledDate(time) {
if (!val) {
return time.getTime() > Date.now()
}
// TODO 如果没有值,需要恢复可选择的状态
const time1 = new Date(val).getTime()
// 当前时间
time = time.getTime()
const start = new Date(val).getTime() - timeRange * 1000
const min = time1 > Date.now() ? Date.now() : time1
return time > min || (useTimeRange && time < start)
}
}
}
},
},
computed: {
defaultStartValue() {
if (this.useTimeRange && this.end_time) {
const time = new Date(this.end_time).getTime() - this.timeRange * 1000
return parseTime(time, '{y}-{m}-{d} {h}:{i}:{s}')
}
return ''
},
defaultEndValue() {
if (this.useTimeRange && this.start_time) {
const time = new Date(this.start_time).getTime() + this.timeRange * 1000
return parseTime(time, '{y}-{m}-{d} {h}:{i}:{s}')
}
return ''
}
},
data() {
return {
start_time: '',
end_time: '',
hack_time: '',
startPickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now()
},
// selectableRange: '00:00:00 - 23:59:59'
},
endPickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now()
},
// selectableRange: '00:00:00 - 23:59:59'
},
}
},
methods: {
// 开始时间的变化
startTimeChange(val) {
if (this.end_time && val && (new Date(val).getTime() > new Date(this.end_time).getTime())) {
this.start_time = ''
this.$message.warning('开始时间不能小于结束时间')
}
this.update()
},
// 结束时间的变化
endTimeChange(val) {
if (this.start_time && val && (new Date(val).getTime() < new Date(this.start_time).getTime())) {
this.end_time = ''
this.$message.warning('结束时间不能大于开始时间')
}
this.update()
},
// 更新数据
update() {
const range = [this.start_time || '', this.end_time || '']
this.$emit('input', range)
this.$emit('change', range)
}
}
}
</script>
<style scoped lang="scss">
//.com-time-range.size36 {
// .com-time-range-item {
// /deep/ .el-input__inner {
// height: 36px;
// line-height: 36px;
// font-size: 14px;
// }
// /deep/ .el-input__icon {
// font-size: 14px;
// line-height: 36px;
// }
// }
//}
//.com-time-range.size38 {
// .com-time-range-item {
// /deep/ .el-input__inner {
// height: 38px;
// line-height: 38px;
// font-size: 16px;
// }
// /deep/ .el-input__icon {
// line-height: 38px;
// }
// }
//}
</style>
2.utils index下 将时间格式转为 年-月-日 时-分-秒
index文件内容:
/**
* 获取本日 本周 本月 时间段
* @param type 类型
* @param cFormat 时间格式化类型 '{y}-{m}-{d} {h}:{i}:{s}'
* @param 1:本日 2:本周 3:本月
*/
export function getDesignatedTime(type, cFormat) {
let time = null
const nowDate = new Date()
const weeKDayLength = 7
// 当前时间是几号
const nowDay = nowDate.getDay()
// 当前时间是星期几 星期天0 => 7
const nowWeekDay = nowDay === 0 ? 7 : nowDate.getDay()
// 当前月
const nowmonth = nowDate.getMonth()
// 当前年
const nowyear = nowDate.getFullYear()
// 本月的开始时间
const monthStartDate = new Date(nowyear, nowmonth, 1)
// 本月的结束时间
const monthEndDate = new Date(nowyear, nowmonth + 1, 0)
if (type === 1) {
time = [parseTime(nowDate, cFormat), parseTime(nowDate, cFormat)]
}
if (type === 2) {
time = [getPreOrNextTime(nowDate, 'pre', 'D', nowWeekDay - 1), getPreOrNextTime(nowDate, 'next', 'D', weeKDayLength - nowWeekDay)]
}
if (type === 3) {
time = [parseTime(monthStartDate), parseTime(monthEndDate)]
}
return time
}
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string | null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string')) {
if ((/^[0-9]+$/.test(time))) {
// support "1548221490638"
time = parseInt(time)
} else {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
time = time.replace(new RegExp(/-/gm), '/')
}
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
return value.toString().padStart(2, '0')
})
return time_str
}
export function splitDateForT(time) {
if (!time) {
return null
}
return time.substring(0, 10)
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
/**
* @param {time} 需要转化的时间
* @param {type} next 下一时间段 pre 前一时间段
* @returns {timeType} 时间类型 小时h 分钟m 天d
* @returns {num} 需要转化的值
*/
export function getPreOrNextTime(time, type, timeType, num) {
time = new Date(time).getTime()
let s = 0
if (timeType === 'D') {
s = num * 1000 * 60 * 60 * 24
}
if (timeType === 'H') {
s = num * 60 * 60 * 1000
}
if (timeType === 'M') {
s = num * 60 * 1000
}
if (type === 'next') {
time = time + s
}
if (type === 'pre') {
time = time - s
}
return parseTime(new Date(time), '{y}-{m}-{d} {h}:{i}:{s}')
}
3.在页面中引入时间组件
html部分:
// 引入日期时间选择器
<com-time-range
v-model="timeRange"
/>
js部分:
computed: {
// 时间范围
timeRange: {
get() {
const { start_time, end_time } = this.value
return [start_time || '', end_time || '']
},
set(val) {
this.$emit('input',{
...this.value,
start_time: (val && val.length) ? val[0] : '',
end_time: (val && val.length) ? val[1] : '',
})
}
},
},