写在前面
需求:elementui中日期时间选择器,目前只能通过点击input输入框触发日期选择器,我希望能通过其他方式触发日期选择器同时把input输入框去掉,如点击按钮
1. 自定义的日期时间组件CustomDatePicker.vue
<template>
<div class="date-input">
<el-input
v-model.trim="startDateStr"
:placeholder="$t('task.taskStartTime')"
type="text"
clearable
class="date-input-field"
@blur="validateDate('startDateStr')"
/>
<!-- <transition name="fade">
<p v-if="error" class="error-message">{{ error }}</p>
</transition> -->
<span class="line"></span>
<el-input
v-model.trim="endDateStr"
:placeholder="$t('task.taskFinishTime')"
type="text"
clearable
class="date-input-field"
@blur="validateDate('endDateStr')"
/>
<!-- <transition name="fade">
<p v-if="error" class="error-message">{{ error }}</p>
</transition> -->
<div class="icon-container" @click="toggleDatePicker">
<i class="el-icon-date" style="font-size: 24px;"></i>
</div>
<el-date-picker
popper-class="dataPickPopperStyle"
class="dataPickStyle"
style="
position: absolute;
z-index: -100;
top: 15px;
left: -178px;
transform: scale(0.1);
"
size="mini"
v-model="selectedDateRange"
:editable="false"
type="datetimerange"
@change="onDateChange"
ref="timePick"
value-format="yyyy-MM-dd HH:mm:ss"
/>
</div>
</template>
<script>
export default {
props: {
customTimePicker: {
type: Array,
default: () => {
return [new Date(), new Date()]
}
},
},
data() {
return {
selectedDateRange: [],
startDateStr: "",
endDateStr: "",
error: ''
};
},
created(){
console.log('====> customTimePicker', this.customTimePicker);
},
watch: {
customTimePicker: {
handler(newVal) {
console.log('customTimePicker==>newVal', newVal);
if (newVal && newVal.length === 2) {
this.selectedDateRange = [...newVal];
this.startDateStr = newVal[0];
this.endDateStr = newVal[1];
}
},
deep: true
},
selectedDateRange: {
handler(newVal, oldVal) {
if (newVal && newVal.length === 2) {
if(oldVal && newVal.toString() === oldVal.toString()) {
return;
} else {
this.startDateStr = newVal[0].toString().replace('T', ' ');
this.endDateStr = newVal[1].toString().replace('T', ' ');
this.$emit('input', newVal);
}
}
},
deep: true
},
startDateStr(newVal, oldVal) {
if(oldVal && newVal.toString() === oldVal.toString()) {
return;
} else {
this.selectedDateRange[0] = newVal.toString().replace('T', ' ');
this.$emit('input', this.selectedDateRange);
}
},
endDateStr(newVal, oldVal) {
if(oldVal && newVal.toString() === oldVal.toString()) {
return;
} else {
this.selectedDateRange[1] = newVal.toString().replace('T', ' ');
this.$emit('input', this.selectedDateRange);
}
}
},
methods: {
validateDate(target) {
let value = '';
if(target === 'startDateStr'){
value = this.startDateStr;
}else if(target === 'endDateStr'){
value = this.endDateStr;
}
// if (value.trim() === '') {
// this.error = '';
// this.$emit('updateError', this.error);
// return;
// }
// 验证格式
const regex = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/;
const match = value.match(regex);
if (!match) {
this.$message.error('Invalid date format. Please use yyyy-MM-dd HH:mm:ss.');
//this.error = 'Correct format is yyyy-MM-dd HH:mm:ss';
// this.$emit('updateError', this.error);
return;
}
// 解析日期
const [year, month, day, hours, minutes, seconds] = match.slice(1).map(Number);
// 检查年份是否在合理范围内
if (year < 1900 || year > 2100) {
this.$message.error('Invalid year. Please enter a year between 1900 and 2100.');
// this.error = 'please input valid year';
// this.$emit('updateError', this.error);
return;
}
// 检查月份是否在1到12之间
if (month < 1 || month > 12) {
this.$message.error('Invalid month. Please enter a month between 1 and 12.');
// this.error = 'please input valid month';
// this.$emit('updateError', this.error);
return;
}
// 检查日期是否在1到当月的最大天数之间
const daysInMonth = new Date(year, month, 0).getDate();
if (day < 1 || day > daysInMonth) {
this.$message.error('Invalid day. Please enter a day between 1 and the maximum number of days in the selected month.');
// this.error = 'please input valid day';
// this.$emit('updateError', this.error);
return;
}
// 检查小时是否在0到23之间
if (hours < 0 || hours > 23) {
this.$message.error('Invalid hour. Please enter an hour between 0 and 23.');
// this.error = 'please input valid hour';
// this.$emit('updateError', this.error);
return;
}
// 检查分钟是否在0到59之间
if (minutes < 0 || minutes > 59) {
this.$message.error('Invalid minute. Please enter a minute between 0 and 59.');
// this.error = 'please input valid minute';
// this.$emit('updateError', this.error);
return;
}
// 检查秒是否在0到59之间
if (seconds < 0 || seconds > 59) {
this.$message.error('Invalid second. Please enter a second between 0 and 59.');
// this.error = 'please input valid second';
// this.$emit('updateError', this.error);
return;
}
// 创建日期对象
const date = new Date(year, month - 1, day, hours, minutes, seconds);
// 检查日期是否有效
if (isNaN(date.getTime())) {
this.$message.error('Invalid date. Please enter a valid date.');
// this.error = 'please input valid date';
// this.$emit('updateError', this.error);
return;
}
this.error = '';
this.$emit('updateError', this.error);
},
formatDate(date) {
if (!date) return '';
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
parseDate(value) {
const parsedDate = new Date(value);
return !isNaN(parsedDate.getTime()) ? parsedDate : null;
},
toggleDatePicker() {
//触发日期框展开
// document
// .querySelector(".time-date-picker")
// .querySelector("input")
// .focus();
this.$refs.timePick.focus();
},
onDateChange(date) {
this.startDateStr = date[0];
this.endDateStr = date[1];
this.$set(this, 'selectedDateRange', [this.startDateStr, this.endDateStr])
this.$emit('input', this.selectedDateRange);
},
},
};
</script>
<style scoped>
.date-input {
display: flex;
align-items: center;
position: relative; /* 为绝对定位的日期选择器提供相对定位 */
}
.date-input-field {
width: 18%;
/* flex-grow: 1; /* 让输入框占满剩余空间 */
/* margin: 0; /* 删除外边距 */
z-index: 10;
}
.icon-container {
display: flex;
align-items: center;
justify-content: center;
/*width: 30px; /* 正方形框的宽度 */
/*height: 30px; /* 正方形框的高度 */
/*border: 1px solid #ccc; /* 正方形框的边框 */
cursor: pointer;
/*background-color: #f9f9f9; /* 可以选择性添加背景色 */
background: transparent;
color: #008ed0;
/*border: 1px solid #008ed0;
}
.icon {
font-size: 16px; /* 调整图标大小 */
font-weight: bold; /* 粗体字 */
margin: 0; /* 删除图标的外边距 */
}
/*
.timePickCSS {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
}
*/
.line {
display: inline-block;
width: 10px;
height: 2px;
background-color: #005987;
}
.error-message {
color: red;
position: absolute;
top: calc(100% - 7px); /* 确保在输入框下方 */
left: 0;
width: 100%;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
2. 页面效果
总结
写这篇博客主要的目的是让自己更深刻,有回忆点,然后就是分享自己的做法;有需要的根据自己的需求进行修改
写在最后
如果此文对您有所帮助,请帅戈靓女们务必不要吝啬你们的Zan,感谢!!不懂的可以在评论区评论,有空会及时回复。