element-ui日期范围组件之改造

element-ui现成的日期范围组件

element-ui提供了日期范围组件,方便直接使用,但交互体验被产品喷,甚至被后端喷(手动捂脸),主要表现为:

  • 开始结束日期每次得重新选择
  • 区间跨度大的时候选择不方便
  • v-model绑定的是一个数组[startDate, endDate],和input/select这些格格不入,提交表单时得额外处理数据

平常就是这么用的:绑定一个range数组,不能直接绑定表单的startDate/endDate

<el-form-item class="c2" label="营业期限" prop="termDateRange" required>
    <el-date-picker
      v-model="form.termDateRange"
      style="width: 100%"
      type="daterange"
      range-separator="至"
      start-placeholder="开始日期"
      end-placeholder="结束日期"
      value-format="yyyy-MM-dd"
    />
</el-form-item>

最后将range转为startDate/endDate

const range = this.form.termDateRange
this.form.termStartDate = range ? range[0] : ''
this.form.termEndDate = range ? range[1] : ''

所以,前端也看他不爽

自己封装的日期范围组件

于是就想到封装一个日期范围组件,

  • 由两个日期选择器合成,开始日期、结束日期分开选择但相互关联,不会出现结束日期早于开始日期
  • 单个的日期选择可以先选择年份,再选择月份和日期,解决了日期跨度大选择不便
  • 不用和一个数组绑定了

上代码

<template>
  <div class="flex">
    <el-form-item class="fill" :prop="startProp" :rules="rules">
      <el-date-picker
        v-model="form[startProp]"
        style="width: 100%"
        type="date"
        placeholder="选择日期"
        format="yyyy-MM-dd"
        value-format="yyyy-MM-dd"
        @change="onStartChange"
      />
    </el-form-item>
    <span class="margin-sm-lr">-</span>
    <el-form-item class="fill" :prop="endProp" :rules="rules">
      <el-date-picker
        v-model="form[endProp]"
        style="width: 100%"
        type="date"
        placeholder="选择日期"
        format="yyyy-MM-dd"
        value-format="yyyy-MM-dd"
        @change="onEndChange"
      />
    </el-form-item>
  </div>
</template>
import moment from 'moment'
export default {
  name: 'VDateRange',
  props: {
    // 表单中开始日期的字段
    startProp: {
      type: String,
      default: ''
    },
    // 表单中结束日期的字段
    endProp: {
      type: String,
      default: ''
    },
    // 是否必填项
    required: {
      type: Boolean,
      default: false
    },
    form: {
      type: Object,
      default: () => {}
    }
  },
  computed: {
    rules () {
      return { required: this.required, message: '必填项' }
    }
  },
  methods: {
    onStartChange (start) {
    // 开始日期晚于结束日期时,结束日期自动设置为开始日期
      const isAfter = moment(start).isAfter(this.form[this.endProp])
      if (isAfter) {
        this.form[this.endProp] = start
      }
    },
    onEndChange (end) {
    // 结束日期早于开始日期时,开始日期自动设置为结束日期
      const isBefore = moment(end).isBefore(this.form[this.startProp])
      if (isBefore) {
        this.form[this.startProp] = end
      }
    }
  }
}

像这样使用

<el-form ref="form" class="flex flex-wrap space-between cols-5" :model="form" label-position="top">
  <el-form-item label="日期区间" class="c2" required>
    <VDateRange start-prop="start" end-prop="end" :form="form" required />
  </el-form-item>
</el-form>


欢迎提出改进意见

posted @ 2020-08-31 16:25  1L  阅读(915)  评论(0)    收藏  举报