季度选择器Vue2

489 阅读1分钟

季度选择器在element2.15.14版本上并没有,但是在业务开发中又非常的需要,所以就封装一个DateQuarterPicker季度选择组件来看看

需求:

  • el-dataPicker的基本功能,DateQuarterPicker要支持
  • 设计的美观一点

思路&注意事项

  1. 选用el-inputel-popover实现
  2. el-input设置只读且事件冒泡
  3. el-popover的显示和隐藏时机
  4. DateQuarterPicker传出的参数

完整代码

<template>
  <div class="quarter-picker-wrap">
    <el-popover v-model="showCard" placement="bottom-start" title="" trigger="manual"content="" width="320">
      <el-input
        slot="reference"
        v-model="showText"
        placeholder="请选择季度"
        clearable
        prefix-icon="el-icon-date"
        readonly
        @click.stop.native="showCard = true"
      >
        <i v-show="showText" slot="suffix" class="el-icon-close" @click.stop="clearQuarter"/>
      </el-input>
      <div style="width: 100%">
        <!-- 年份切换 -->
        <div class="yearChangeBox" style="display: flex;width: 100%;align-items: center;justify-content: space-between">
          <div>
            <el-button icon="el-icon-d-arrow-left" type="text" style="color:#303133;" @click="changeYear('prev')"/>
          </div>
          <div class="font-16">{{ showYear }}</div>
          <div>
            <el-button icon="el-icon-d-arrow-right" type="text" style="color:#303133;" @click="changeYear('next')"/>
          </div>
        </div>

        <!-- 季度切换 -->
        <div class="quarterChangeBox">
          <div v-for="(item) in quarterList" :key="item.value">
            <div :class="selectedYear===showYear&&selectedQuarter===item.label? 'selecedQuarterItem':''" style="cursor: pointer;text-align: center" class="quarterItem" @click="changeQuarter(item)">{{ item.label }}</div>
          </div>
        </div>
      </div>
    </el-popover>
  </div>
</template>

<script>
export default {
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: {
      type: [String, Number],
      default: ''
    }
  },
  data() {
    return {
      showCard: false,
      selectTime: '', // 当前选中时间,格式为2023Q3

      showYear: null, // 展示的

      selectedYear: null, // 被选中的年
      selectedQuarter: '', // 被选中的季度

      quarterList: [
        { label: 'Q1', qStartDate: '-01-01', qEndDate: '-03-31', value: 1 },
        { label: 'Q2', qStartDate: '-04-01', qEndDate: '-06-30', value: 2 },
        { label: 'Q3', qStartDate: '-07-01', qEndDate: '-09-30', value: 3 },
        { label: 'Q4', qStartDate: '-10-01', qEndDate: '-12-31', value: 4 }]
    }
  },
  computed: {
    // 格式化当前选中的时间并展示
    showText() {
      if (!this.selectTime) {
        return ''
      } else {
        return this.selectTime
      }
    }
  },
  watch: {
    value: {
      immediate: true,
      handler: function(value) {
        if (!value) {
          this.selectTime = '' // 当前选中时间
          const currentDateTime = new Date()
          this.showYear = currentDateTime.getFullYear()
          this.selectedYear = ''
          this.selectedQuarter = ''
        } else {
          this.selectTime = value
          this.showYear = Number(value.slice(0, 4))
          this.selectedYear = Number(value.slice(0, 4))
          this.selectedQuarter = value.slice(4, 7)
        }
      }
    }
  },
  mounted() {
    // 监听全局按钮的点击
    const that = this
    document.body.addEventListener('click', function() {
      that.showCard = false
    })
  },
  methods: {
    // 切换年份
    changeYear(type = '') {
      if (type === 'next') {
        this.showYear = this.showYear + 1
      } else if (type === 'prev') {
        this.showYear = this.showYear - 1
      }
    },

    // 切换事件
    changeQuarter(quarter) {
      this.selectedQuarter = quarter.label
      this.selectedYear = this.showYear
      const obj = {
        selectTime: this.selectedYear + this.selectedQuarter,
        selectNumber: this.selectedYear + this.selectedQuarter.substr(-1) - 0, // 20231
        selectQStartDate: this.selectedYear + quarter.qStartDate,
        selectQEndDate: this.selectedYear + quarter.qEndDate,
        value: quarter.value
      }
      this.selectTime = obj.selectTime
      this.showCard = false
      this.$emit('change', this.selectTime)
      this.$emit('selectChange', obj)
    },
    // 清空事件默认触发selectChange
    clearQuarter() {
      this.$emit('change', '')
      const obj = {
        selectTime: '',
        selectNumber: 0,
        selectQStartDate: '',
        selectQEndDate: '',
        value: 0
      }
      this.$emit('selectChange', obj)
    }
  }
}
</script>

<style lang='scss'>
.yearChangeBox{
  height: 35px;
  border-bottom: 1px solid #e4e7ed;
}
.quarterChangeBox{
  display: flex;
  margin-top:10px ;
  padding: 5px 5px;
  width: calc(100% - 20px);
}
.quarterItem{
  width: 50px;
}
.quarterItem:hover{
  color: #3967FB;
}
.selecedQuarterItem, .selecedQuarterItem:hover{
  background-color: #3967FB;
  color: #ffffff;
  border-radius: 4px;
}
</style>