封装elementUi 时间范围选择组件,支持回显13位,提交10位

<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;
    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值