<time-range-picker `TimeRangePicker` 组件具有以下特性:
1. **时间戳处理**:
- 内部使用13位时间戳(用于显示)
- 对外输出10位时间戳(用于接口)
- 自动处理时间戳的转换
2. **时间范围限制**:
- 默认限制3个月内(可通过 `maxSpan` 属性配置)
- 支持先选择开始时间或结束时间
- 自动禁用超出范围的日期
3. **快捷选项**:
- 最近一周
- 最近一个月
- 最近三个月
4. **可配置项**:
- `clearable`:是否可清除(默认 true)
- `maxSpan`:最大时间跨度,单位月(默认 3)
使用示例:
```vue
<time-range-picker
v-model="dateRange"
v-model="dateRange"earable="true"
@change
:max-span="3"
:clearable="true"
@changeange"
/>这个组件。组件会自动处理:
1. 时间戳的转换(13位显示,10位输出)
2. 时间范围的限制(3个月内)
3. 时间选择的验证和提示
```javascript
在这里插入代码片
子组件
<template>
<el-date-picker
v-model="innerValue"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"
value-format="timestamp"
:clearable="clearable"
@change="handleChange"
>
</el-date-picker>
</template>
<script>
export default {
name: 'TimeRangePicker',
props: {
// v-model绑定值
value: {
type: Array,
default: () => []
},
// 是否可清除
clearable: {
type: Boolean,
default: true
},
// 最大时间跨度(月)
maxSpan: {
type: Number,
default: 3
}
},
data() {
return {
innerValue: this.convertTo13Digits(this.value),
pickerOptions: {
disabledDate: (time) => {
if (!this.innerValue || !this.innerValue.length) {
return false;
}
const currentDate = time.getTime();
// 如果已选择开始时间
if (this.innerValue[0] && !this.innerValue[1]) {
const startTime = new Date(this.innerValue[0]);
const maxEndTime = new Date(startTime);
maxEndTime.setMonth(startTime.getMonth() + this.maxSpan);
return currentDate < startTime.getTime() || currentDate > maxEndTime.getTime();
}
// 如果已选择结束时间
if (!this.innerValue[0] && this.innerValue[1]) {
const endTime = new Date(this.innerValue[1]);
const minStartTime = new Date(endTime);
minStartTime.setMonth(endTime.getMonth() - this.maxSpan);
return currentDate > endTime.getTime() || currentDate < minStartTime.getTime();
}
return false;
},
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 1);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 3);
picker.$emit('pick', [start, end]);
}
}]
}
};
},
watch: {
value: {
handler(val) {
this.innerValue = this.convertTo13Digits(val);
},
deep: true
}
},
methods: {
// 转换为13位时间戳
convertTo13Digits(val) {
if (!val || !val.length) return [];
return val.map(timestamp => {
if (!timestamp) return null;
const strTimestamp = String(timestamp);
return strTimestamp.length === 10 ? Number(strTimestamp) * 1000 : Number(strTimestamp);
});
},
// 转换为10位时间戳
convertTo10Digits(val) {
if (!val || !val.length) return [];
return val.map(timestamp => {
if (!timestamp) return null;
const strTimestamp = String(timestamp);
return strTimestamp.length === 13 ? Math.floor(Number(strTimestamp) / 1000) : Number(strTimestamp);
});
},
// 处理时间变化
handleChange(val) {
if (!val) {
this.$emit('input', []);
this.$emit('change', []);
return;
}
// 检查时间跨度
if (val[0] && val[1]) {
const startDate = new Date(val[0]);
const endDate = new Date(val[1]);
const diffMonths = (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24 * 30);
if (diffMonths > this.maxSpan) {
this.$message.warning(`时间跨度不能超过${this.maxSpan}个月`);
// 自动调整为最大跨度
const adjustedEndDate = new Date(startDate);
adjustedEndDate.setMonth(startDate.getMonth() + this.maxSpan);
this.innerValue = [val[0], adjustedEndDate.getTime()];
val = this.innerValue;
}
}
// 发出10位时间戳
const result = this.convertTo10Digits(val);
this.$emit('input', result);
this.$emit('change', result);
}
}
};
</script>
调用
在这里插入代码片
handleDateRangeChange(val) {
if (!val || !val.length) {
this.reviewForm.create_start_at = 0;
this.reviewForm.create_end_at = 0;
return;
}
// TimeRangePicker 组件已经返回了10位时间戳,直接使用即可
this.reviewForm.create_start_at = val[0] || 0;
this.reviewForm.create_end_at = val[1] || 0;
}