element ui中日期和时间选择器(DateTimePicker)是一个常见且重要的组件。它允许用户轻松地选择日期和时间,极大地提升了用户体验。然而,在某些场景下,用户可能需要更细粒度的控制,例如单独清除已选择的时间而保留日期。效果如下图,本文将带领你一步步封装一个DateTimePicker组件,实现时间的独立清除功能。
实现步骤
1、在components中新建组件dataTimePicker
<template><el-date-picker:popper-class="uniqueId"style="margin-left: 5px"type="datetime"v-model="dataTimeValue":placeholder="placeholder"@change="changeDateTime"@focus="onFocus"></el-date-picker>
</template>
1、1给每个组件自定义一个唯一的下拉框class名
data() {return {dataTimeValue: "", // 初始化值uniqueId: `date-picker-${Math.random().toString(36).substring(2, 15)}`, // 生成一个唯一的IDisAddCloseIcon: false,};},
1.2 该组件接收两个props
props: {timeValue: {type: Date, // 初始展示时间required: false,},placeholder: {type: String,require: false,default: "起始时间",},},
1.3 在 onFocus事件中,添加清除图标,因为只有当onFocus触发时,下拉框才显示,才能获取到下拉框dom
onFocus() {if (this.isAddCloseIcon) return; // 避免重复添加this.$nextTick(() => {this.timeDiv = document.querySelectorAll(`.${this.uniqueId} .el-date-picker__editor-wrap .el-input`,this.$el)[1];this.span = document.createElement("span");this.span.innerHTML = `<i class="el-icon-circle-close"></i>`;this.span.style.position = "absolute";this.span.style.right = "10px";this.span.style.cursor = "pointer";this.span.style.display = "none"; // 初始时隐藏spanthis.timeDiv.appendChild(this.span);// 鼠标移入事件this.timeDiv.addEventListener("mouseenter",this.handleMouseenter);// 鼠标移出事件this.timeDiv.addEventListener("mouseleave", this.handleMouseLeave);// 点击事件,清除时间置为00:00:00this.span.addEventListener("click", this.clearDateTimeValue);this.isAddCloseIcon = true;});},
1.4 清除时间事件以及鼠标移入显示图标移除隐藏图标:
clearDateTimeValue() {this.dataTimeValue = this.$moment(this.dataTimeValue).startOf("day").toISOString();},handleMouseLeave() {this.span.style.display = "none";},handleMouseenter() {this.span.style.display = "inline";}
1.5 时间变化时通知父组件:
changeDateTime(value) {this.dataTimeValue = value;this.$emit("change", value);},
1.6 组件销毁时,移除监听事件:
beforeDestroy() {// 组件销毁前清理事件监听器this.span.removeEventListener('click',this.clearDateTimeValue)this.timeDiv.removeEventListener('mouseenter',this.handleMouseenter)this.timeDiv.removeEventListener('mouseleave',this.handleMouseLeave)this.span = nullthis.timeDiv = null},
完整代码:
dataTimePicker.vue:
<template><el-date-picker:popper-class="uniqueId"style="margin-left: 5px"type="datetime"v-model="dataTimeValue":placeholder="placeholder"@change="changeDateTime"@focus="onFocus"></el-date-picker>
</template><script>
export default {props: {timeValue: {type: Date,required: false,},placeholder: {type: String,require: false,default: "起始时间",},},data() {return {dataTimeValue: "", // 初始化值uniqueId: `date-picker-${Math.random().toString(36).substring(2, 15)}`, // 生成一个唯一的IDisAddCloseIcon: false,};},mounted() {this.dataTimeValue = this.timeValue;},methods: {changeDateTime(value) {this.dataTimeValue = value;this.$emit("change", value);},onFocus() {if (this.isAddCloseIcon) return; // 避免重复添加this.$nextTick(() => {this.timeDiv = document.querySelectorAll(`.${this.uniqueId} .el-date-picker__editor-wrap .el-input`,this.$el)[1];this.span = document.createElement("span");this.span.innerHTML = `<i class="el-icon-circle-close"></i>`;this.span.style.position = "absolute";this.span.style.right = "10px";this.span.style.cursor = "pointer";this.span.style.display = "none"; // 初始时隐藏spanthis.timeDiv.appendChild(this.span);// 鼠标移入事件this.timeDiv.addEventListener("mouseenter",this.handleMouseenter);// 鼠标移出事件this.timeDiv.addEventListener("mouseleave", this.handleMouseLeave);this.span.addEventListener("click", this.clearDateTimeValue);this.isAddCloseIcon = true;});},clearDateTimeValue() {this.dataTimeValue = this.$moment(this.dataTimeValue).startOf("day").toISOString();},handleMouseLeave() {this.span.style.display = "none";},handleMouseenter() {this.span.style.display = "inline";}},beforeDestroy() {// 组件销毁前清理事件监听器this.span.removeEventListener('click',this.clearDateTimeValue)this.timeDiv.removeEventListener('mouseenter',this.handleMouseenter)this.timeDiv.removeEventListener('mouseleave',this.handleMouseLeave)this.span = nullthis.timeDiv = null},
};
</script>
2、在父组件引入:
<template>
<dateTimePicker :timeValue="startTime" @change="changeDateTime"></dateTimePicker>
</template>
<script type="text/ecmascript-6">
import dateTimePicker from '@/components/dataTimePicker.vue'
export default {
...,methods: {changeDateTime(value) {console.log('变化',value)
}
}
</script>
3、总结
通过以上方法,我们可以实现在不改变日期的情况下单独清除时间功能,实际上就是在element ui原本的el-date-picker组件上进行改装,增加一个清除按钮并绑定清除事件来实现。实际应用中,你可以根据具体需求进一步扩展和定制这个组件,以满足不同场景下的使用。希望这篇文章能对你有所帮助!