• 开始结束日期每次得重新选择
  • 区间跨度大的时候选择不方便
  • 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>
    </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>
    

    欢迎提出改进意见