根据产品需求和使用场景,将elementUi的时间选择器二次封装(将整体的时间段选择拆分成两个单独时间的选择)方便以后的维护或框架的修改。
<template>
<div
class="public-date"
:style="{maxWidth:width}"
>
<el-date-picker
v-model="startTime"
v-bind="$attrs"
class="date-custom"
:size="size"
:type="type"
:picker-options="pickerOptions"
:placeholder="startPlaceholder"
:value-format="valueFormat"
@change="changeDatePickerHandler"
>
</el-date-picker>
<span class="mar-lr5">{{rangeSeparator}}</span>
<el-date-picker
v-model="endTime"
v-bind="$attrs"
class="date-custom"
:size="size"
:type="type"
:picker-options="endTimeOption"
:placeholder="endPlaceholder"
:value-format="valueFormat"
@change="changeDatePickerHandler"
>
</el-date-picker>
</div>
</template>
<script>
import { utility } from "@/assets/js/common";
export default {
inheritAttrs: false,
name: "PublicDatePicker",
// 参数同element ui文档一致
// 需要改变的默认值用props,否则用attrs
props: {
// 绑定值(必传)
value: {
type: Array | String,
required: true,
},
// 显示类型
type: {
type: String,
default: "datetime",
},
// 输入框尺寸
size: {
type: String,
default: "mini",
},
width: {
type: String,
default: "380px",
},
// 可选,绑定值的格式。不指定则绑定值为 Date 对象
valueFormat: {
type: String,
// timestamp
default: "yyyy-MM-dd HH:mm:ss",
},
// 日期选择器选项
pickerOptions: {
type: Object,
default: () => {
return {};
},
},
// 选择范围时的分隔符
rangeSeparator: {
type: String,
default: "~",
},
// 范围选择时开始日期的占位内容
startPlaceholder: {
type: String,
default: "选择开始时间",
},
// 范围选择时结束日期的占位内容
endPlaceholder: {
type: String,
default: "选择结束时间",
},
},
data() {
return {
startTime: "",
endTime: "",
endTimeOption: {},
disabledDate: null,
};
},
watch: {
value: {
handler(nVal) {
if (Array.isArray(nVal) && nVal.length) {
this.startTime = nVal[0] || "";
this.endTime = nVal[1] || "";
} else {
// 数据格式去重置
this.emitEventHandler();
}
},
immediate: true,
},
},
created() {
// 获取时间限制函数
// 深拷贝方法utility.deepClone
this.endTimeOption = utility.deepClone(this.pickerOptions);
if (this.pickerOptions.disabledDate) {
this.disabledDate = utility.deepClone(
this.pickerOptions.disabledDate
);
}
// 对结束时间增加限制
this.endTimeOption.disabledDate = (time) => {
let flag = false;
if (this.startTime) {
if (
new Date(this.startTime).getTime() - 24 * 3600 * 1000 + 1 >
time.getTime()
) {
return true;
}
}
// props传入限制
if (
Object.prototype.toString.call(this.disabledDate) ==
"[object Function]"
) {
flag = flag || this.disabledDate(time);
}
return flag;
};
},
methods: {
changeDatePickerHandler() {
// 开始时间大于结束时间
if (
new Date(this.startTime).getTime() >
new Date(this.endTime).getTime() &&
new Date(this.endTime).getTime() != 0
) {
this.endTime = "";
this.$message({
message: `开始时间不能大于结束时间`,
type: "error",
});
return;
}
this.emitEventHandler(this.startTime, this.endTime);
},
emitEventHandler(startTime, endTime) {
let value = [startTime || "", endTime || ""];
this.$emit("update:value", value);
this.$emit("input", value);
this.$emit("change", value);
},
},
};
</script>
<style lang="scss" scoped>
.public-date{
width: 100%;
display: flex;
flex-wrap: nowrap;
align-items: center;
.date-custom {
/deep/ .el-input__suffix {
right: 0;
}
/deep/ .el-icon-time {
display: none;
}
/deep/ .el-icon-date {
display: none;
}
/deep/ .el-input__inner {
padding: 0 15px !important;
}
/deep/.el-input__icon {
line-height: 32px;
}
}
.mar-lr5 {
margin: 0 3px;
}
}
</style>
封装的组件是根据产品需求走的,可以自行修改。
换成这种选择器可以只选择开始或结束时间进行查询。但有些场景需要两个时间都选择,可自行编写自定义校验规则。