<template>
<div class="my-date">
<el-date-picker
v-model="selectDateValue"
:value-format="valueFormat"
:type="type"
:align="align"
unlink-panels
:popper-class="clearable ? '' : 'datePickerStyNoClear'"
:range-separator="rangeSeparator"
:start-placeholder="startPlaceholder"
:end-placeholder="endPlaceholder"
:picker-options="pickerOptions"
:size="size"
:default-time="defaultTime"
:clearable="clearable"
@change="handleChangeDate"
@blur="blur"
/>
</div>
</template>
<script>
import { shortcutsOptions, disabledDate } from './index.js';
import moment from 'moment';
import { deepClone } from '../../utils/index.js';
export default {
model: {
prop: 'value',
event: 'changeDate',
},
props: {
// 接收父组件v-mode传入的value值
value: { type: Array, required: true },
// 时间组件的类型
type: {
type: String,
default: 'datetimerange',
},
// 组件的大小,默认小号的
size: {
type: String,
default: 'small',
},
startPlaceholder: {
type: String,
default: '开始日期',
},
endPlaceholder: {
type: String,
default: '结束日期',
},
rangeSeparator: {
type: String,
default: '至',
},
// 日期格式 默认 yyyy-MM-dd HH:mm:ss
// 想要 yyyy-MM-dd 形式的,在父组件传入 yyyy-MM-dd
valueFormat: {
type: String,
required: false,
default: 'yyyy-MM-dd HH:mm:ss',
},
// 日期选择界面的 对齐方式 默认 居中(center)
align: {
type: String,
required: false,
default: 'center',
},
// 是否展示快捷选项
showShortcuts: {
type: Boolean,
default: true,
},
// 默认选择时间
defaultSelectDays: {
type: Number,
default: 0,
},
momentSubtractParams:{
type:String,
default:'days'
},
// 最大时间间隔
maxDateInterval: {
type: Number,
default: 30,
},
// 是否限制可选择时间,需要选择时间大于当前时间时候设置为 true
isLimitTimeSelect:{
type: Boolean,
default: false,
},
formData:{
type:Object,
default:() => ({})
},
showClear: {
type: Boolean,
default: true,
},
// 需要排除得keys
excludeKeys:{
type:Array,
default:() => []
}
},
data() {
let _this = this;
return {
defaultTime:['00:00:00', '23:59:59'],
clearable:true,
selfFormData:{},
selectDateValue: [], // 选择日期存放的值
pickerMinDate: null,
pickerOptions: {
disabledDate: (time) => disabledDate(time, _this),
// 配置快捷日期选择
shortcuts: shortcutsOptions(_this),
onPick: (val) => {
if (val.minDate && this.pickerMinDate) {
this.pickerMinDate = null;
} else if (val.minDate) {
this.pickerMinDate = val.minDate.getTime();
}
},
},
};
},
watch: {
formData:{
deep:true,
handler(val) {
// 判断两个对象是否相同
// const isChange = isObjectValueEqual(this.delectKeys(val), this.delectKeys(this.selfFormData));
const changeFn = (obj) => {
return Object.values(obj).every(item => {
if (typeof item === 'object' && item !== null && !(item instanceof Date)) {
if (Array.isArray(item)) {
return !item.length;
}
return changeFn(item);
}
return !item && (item !== 0);
});
};
const isChange = changeFn(this.delectKeys(val));
if (isChange) {
this.setDefaultDate();
this.clearable = false;
} else {
this.clearable = true;
}
}
},
value: {
immediate: true,
handler(val) {
this.selectDateValue = val;
},
},
},
created() {
this.clearable = this.showClear;
// 如果没有赋值,不执行该操作
if (Object.keys(this.formData).length > 0) {
this.selfFormData = deepClone(this.formData);
this.clearable = false;
}
// 组件赋默认值
if (this.defaultSelectDays > 0) {
this.setDefaultDate();
}
},
methods: {
// 选择日期触发的事件
handleChangeDate(val) {
this.$emit('changeDate', val || []);
},
setDefaultDate() {
const correctDefaultSelectDays = this.valueFormat === 'yyyy-MM-dd HH:mm:ss' ? (this.defaultSelectDays - 1) : this.defaultSelectDays;
// 如果要时分秒
if (this.type === 'daterange' && this.valueFormat !== 'yyyy-MM-dd HH:mm:ss') {
const date = [moment().subtract(correctDefaultSelectDays, 'days').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
this.handleChangeDate(date);
return;
}
const date = [moment().subtract(correctDefaultSelectDays, 'days').format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD 23:59:59')];
this.handleChangeDate(date);
},
delectKeys(obj) {
const newObj = deepClone(obj);
this.excludeKeys.forEach(item => {
delete newObj[item];
});
return newObj;
},
blur() {
this.pickerMinDate = null;
}
},
};
</script>
<style scoped lang='scss'>
::v-deep.el-date-editor--daterange.el-input,
.el-date-editor--daterange.el-input__inner,
.el-date-editor--timerange.el-input,
.el-date-editor--timerange.el-input__inner {
width: 400px;
}
.datePickerStyNoClear .el-picker-panel__footer .el-button--text span {
display: none !important;
}
</style>
import moment from 'moment';
export const getDefaultTime = () => {
const startFormat = moment(new Date()).format('YYYY-MM-DD 00:00:00');
const start = new Date(startFormat);
const endFormat = moment(new Date()).format('YYYY-MM-DD 23:59:59');
const end = new Date(endFormat);
return {
start,
end,
};
};
// 快捷选项 7天
const selectOption7Day = (_this) => {
return [
{
text: '今天',
onClick(picker) {
const { start, end } = getDefaultTime();
picker.$emit('pick', [start, end]);
},
},
{
text: '昨天',
onClick(picker) {
const { start, end } = getDefaultTime();
end.setTime(end.getTime() - 3600 * 1000 * 24);
start.setTime(start.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', [start, end]);
},
},
{
text: '过去7天',
onClick:(picker) => {
const { start, end } = getDefaultTime();
const minusDay = _this.valueFormat === 'yyyy-MM-dd HH:mm:ss' ? 6 : 7;
start.setTime(start.getTime() - 3600 * 1000 * 24 * minusDay);
picker.$emit('pick', [start, end]);
},
}
];
};
// 快捷选项 30天
const selectOption30Day = (_this) => {
return [
...selectOption7Day(_this),
{
text: '过去30天',
onClick(picker) {
const { start, end } = getDefaultTime();
const minusDay = _this.valueFormat === 'yyyy-MM-dd HH:mm:ss' ? 29 : 30;
start.setTime(start.getTime() - 3600 * 1000 * 24 * minusDay);
picker.$emit('pick', [start, end]);
},
}
];
};
// 快捷选项 60天
const selectOption60Day = (_this) => {
return [
...selectOption30Day(_this),
{
text: '过去60天',
onClick(picker) {
const { start, end } = getDefaultTime();
const minusDay = _this.valueFormat === 'yyyy-MM-dd HH:mm:ss' ? 59 : 60;
start.setTime(start.getTime() - 3600 * 1000 * 24 * minusDay);
picker.$emit('pick', [start, end]);
},
},
];
};
// 快捷选项 90天
const selectOption90Day = (_this) => {
return [
...selectOption60Day(_this),
{
text: '过去90天',
onClick(picker) {
const { start, end } = getDefaultTime();
const minusDay = _this.valueFormat === 'yyyy-MM-dd HH:mm:ss' ? 89 : 90;
start.setTime(start.getTime() - 3600 * 1000 * 24 * minusDay);
picker.$emit('pick', [start, end]);
},
},
];
};
export const shortcutsOptions = (_this) => {
if (_this.showShortcuts) {
if ( _this.maxDateInterval < 7) {
return null;
} else if (_this.maxDateInterval >= 7 && _this.maxDateInterval < 30) {
return selectOption7Day(_this);
} else if (_this.maxDateInterval >= 30 && _this.maxDateInterval < 60) {
return selectOption30Day(_this);
} else if (_this.maxDateInterval >= 60 && _this.maxDateInterval < 90) {
return selectOption30Day(_this);
}
return selectOption90Day(_this);
}
return null;
};
export const disabledDate = (time, _this) => {
const maxDateIntervalTmime = (_this.maxDateInterval) * 24 * 3600 * 1000;
if (_this.isLimitTimeSelect) {
// 当不限制时间选择的时候,需要设定最大时间跨度
if (_this.pickerMinDate) {
return (
time.getTime() >= (_this.pickerMinDate + maxDateIntervalTmime) ||
time.getTime() <= _this.pickerMinDate - maxDateIntervalTmime
);
}
return false;
}
if (_this.pickerMinDate) {
return (
time.getTime() >= (((_this.pickerMinDate + maxDateIntervalTmime) > new Date(moment(new Date()).format('YYYY,MM,DD 23:59:59'))) ? new Date(moment(new Date()).format('YYYY,MM,DD 23:59:59')) : (_this.pickerMinDate + maxDateIntervalTmime)) ||
time.getTime() <= (((_this.pickerMinDate - maxDateIntervalTmime) < new Date(2018, 0, 18)) ? new Date(2018, 0, 18) : (_this.pickerMinDate - maxDateIntervalTmime))
);
}
return (
time.getTime() >
new Date(moment(new Date()).format('YYYY,MM,DD 23:59:59')) ||
time.getTime() < new Date(2018, 0, 18)
);
};
<zz-time-picker v-model="appearDate" size="" :defaultSelectDays="30" />
1.父组件再页面首次加载时候,要获得appearDate的值,需要再mounted中使用(组件的加载顺序问题)
2.如果时间组件必须有值,设置showClear为false
3.如果筛选条件为空时候,时间必填,不为空时候,时间可填可不填,传入搜索条件的数据formData和需要排除的keys数组excludeKeys。组件会自动判断是否需要重新填充时间。