Files
orange-admin/orange-demo-single-pg/orange-demo-single-pg-web/src/components/DateRange/index.vue
2022-02-20 13:40:36 +08:00

306 lines
7.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="date-range">
<!--<year-range-panel />-->
<el-select v-model="dateType" :size="size"
style="max-width: 100px; min-width: 100px; margin-right: 10px;"
v-if="!hideTypeOnlyOne || validTypeList.length > 1">
<el-option v-for="type in validTypeList" :key="type.value" :value="type.value" :label="type.label" />
</el-select>
<el-date-picker style="flex-grow: 1;" v-model="currentDates"
:size="size" :placeholder="placeholder" :type="innerDateType"
:disabled="disabled" :format="innerDateFormat" :readonly="readonly" :editable="editable"
:clearable="clearable" :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder"
:align="align" :range-separator="rangeSeparator" :value-format="valueFormat"
:prefix-icon="prefixIcon" :clear-icon="clearIcon" @change="onValueChange" />
</div>
</template>
<script>
import { formatDate, parseDate } from 'element-ui/src/utils/date-util';
const allTypeList = [{
value: 'day',
label: '自然日'
}, {
value: 'month',
label: '自然月'
}, {
value: 'year',
label: '自然年'
}];
export default {
name: 'DateRange',
props: {
/**
* 绑定的数据
*/
value: {
type: [Array],
default: () => {
return []
}
},
/**
* 默认显示的数据选择方式如果不存在与allowTypes中则显示allowTypes中的第一个
*/
defaultDateType: {
type: String,
default: 'day'
},
/**
* 组件大小medium / small / mini
*/
size: {
type: String
},
/**
* 数据选择方式只有一个的时候是否隐藏数据选择方式下拉
*/
hideTypeOnlyOne: {
type: Boolean,
default: true
},
/**
* 允许的数据选择方式day, month, year
* 默认值['day', 'month', 'year']
*/
allowTypes: {
type: Array,
default: () => {
return allTypeList.map((item) => {
return item.value;
});
}
},
/**
* 是否范围选择
*/
isRange: {
type: Boolean,
default: true
},
/**
* 输出字符串的format
*/
outputFormat: {
type: String,
default: 'yyyy-MM-dd HH:mm:ss'
},
/**
* 非范围选择时的占位内容
*/
placeholder: String,
/**
* 范围选择时开始日期的占位内容
*/
startPlaceholder: String,
/**
* 范围选择时结束日期的占位内容
*/
endPlaceholder: String,
/**
* 完全只读
*/
readonly: Boolean,
/**
* 禁用
*/
disabled: Boolean,
/**
* 文本框可输入
*/
editable: {
type: Boolean,
default: true
},
/**
* 是否显示清除按钮
*/
clearable: {
type: Boolean,
default: true
},
/**
* 对齐方式left, center, right
*/
align: {
type: String,
default: 'left'
},
/**
* 选择范围时的分隔符
*/
rangeSeparator: {
type: String,
default: '-'
},
/**
* 可选,绑定值的格式。不指定则绑定值为 Date 对象
*/
valueFormat: {
type: String,
default: 'yyyy-MM-dd'
},
/**
* 自定义头部图标的类名
*/
prefixIcon: {
type: String,
default: 'el-icon-date'
},
/**
* 自定义清空图标的类名
*/
clearIcon: {
type: String,
default: 'el-icon-circle-close'
}
},
data () {
return {
dateType: this.defaultDateType,
currentDates: undefined
}
},
methods: {
onValueChange (values) {
this.$nextTick(() => {
this.emitChange();
});
},
emitChange () {
let outputDate = [];
if (this.currentDates != null) {
if (!this.isRange) {
outputDate[0] = new Date(this.currentDates);
outputDate[1] = new Date(this.currentDates);
} else {
if (Array.isArray(this.currentDates) && this.currentDates.length === 2) {
outputDate[0] = new Date(this.currentDates[0]);
outputDate[1] = new Date(this.currentDates[1]);
}
}
if (outputDate[0] != null && outputDate[1] != null) {
outputDate[0].setHours(0, 0, 0, 0);
outputDate[1].setHours(0, 0, 0, 0);
switch (this.dateType) {
case 'day':
outputDate[1].setDate(outputDate[1].getDate() + 1);
break;
case 'month':
outputDate[1].setDate(1);
outputDate[0].setDate(1);
outputDate[1].setMonth(outputDate[1].getMonth() + 1);
break;
case 'year':
outputDate[1].setMonth(0);
outputDate[1].setDate(1);
outputDate[0].setMonth(0);
outputDate[0].setDate(1);
outputDate[1].setFullYear(outputDate[1].getFullYear() + 1);
break;
}
outputDate[1] = new Date(outputDate[1].getTime() - 1);
outputDate[0] = formatDate(outputDate[0], this.outputFormat);
outputDate[1] = formatDate(outputDate[1], this.outputFormat);
}
}
this.$emit('input', outputDate);
this.$emit('change', outputDate);
},
getCurrentStatsDateType () {
return this.dateType;
}
},
computed: {
validTypeList () {
return allTypeList.filter((item) => {
return this.allowTypes.indexOf(item.value) !== -1;
});
},
/**
* el-date-picker使用的type
*/
innerDateType () {
switch (this.dateType) {
case 'day': return this.isRange ? 'daterange' : 'date';
case 'month': return this.isRange ? 'monthrange' : 'month';
case 'year': return this.isRange ? 'monthrange' : 'year';
default: return this.isRange ? 'daterange' : 'date';
}
},
/**
* el-date-picker使用的format
*/
innerDateFormat () {
switch (this.dateType) {
case 'day': return 'yyyy-MM-dd';
case 'month': return 'yyyy-MM';
case 'year': return 'yyyy';
default: return 'yyyy-MM-dd';
}
}
},
watch: {
value: {
handler: function (newValue, oldValue) {
if (newValue == null || newValue.length < 2) {
this.currentDates = this.isRange ? [] : undefined;
} else {
if (this.currentDates == null) this.currentDates = [];
if (this.isRange) {
this.currentDates = [
parseDate(newValue[0], this.valueFormat),
parseDate(newValue[1], this.valueFormat)
];
} else {
this.currentDates = parseDate(newValue[0], this.valueFormat);
}
}
},
immediate: true,
deep: true
},
dateType: {
handler: function (newValue, oldValue) {
if (this.allowTypes.indexOf(this.dateType) === -1) {
this.dateType = this.allowTypes[0] || 'day';
}
this.emitChange();
},
immediate: true
},
defaultDateType: {
handler: function (newValue, oldValue) {
if (this.allowTypes.indexOf(newValue) !== -1) {
this.dateType = newValue;
} else {
this.dateType = this.allowTypes[0];
}
}
},
isRange: {
handler: function (newValue, oldValue) {
let temp;
if (newValue) {
temp = [this.currentDates, this.currentDates];
} else {
temp = this.currentDates[0];
}
this.currentDates = temp;
}
}
}
}
</script>
<style scoped>
.date-range {
display: flex;
}
</style>