季度选择下拉框

季度选择下拉框

HTML

在这里插入图片描述

<template>
  <div class="default-season-picker">
    <mark
      style="position:fixed;top:0;bottom:0;left:0;right:0;background:rgba(0,0,0,0);z-index:999;"
      v-show="showSeason"
      @click.stop="showSeason=false"
    ></mark>
    <el-input placeholder="请选择季度" v-model="showValue" style="width:210px;" readonly @focus="openSeason">
      <i slot="prefix" class="el-input__icon el-icon-date"></i>
    </el-input>
    <el-card class="box-card" v-show="showSeason">
      <div slot="header" class="clearfix" style="text-align:center;padding:0">
        <!-- 季度 -->
        <div v-show="seasonPicker">
          <button
            type="button"
            aria-label="前一年"
            class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"
            @click="prevSeason"
          ></button>
          <span @click="openYear" role="button" class="el-date-picker__header-label">{{ year }}年</span>
          <button
            type="button"
            aria-label="后一年"
            @click="nextSeason"
            class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right"
          ></button>
        </div>
        <!-- 年度 -->
        <div v-show="yearPicker">
          <button
            type="button"
            aria-label="前十年"
            class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"
            @click="prevYear"
          ></button>
          <span @click="openYear" role="button"
                class="el-date-picker__header-label">{{ startYear }}年 - {{ endYear }}年</span>
          <button
            type="button"
            aria-label="后十年"
            @click="nextYear"
            class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right"
          ></button>
        </div>
      </div>
      <!-- 季度 -->
      <div class="text item" v-if="seasonPicker">
        <el-button
          v-for="(item, index) in seasonArr"
          :key="index"
          type="text"
          size="medium"
          :class="{
            'active-button': (lineHeightClass === index && year === yearData && isHeightLineMax) || (isHeightLineMax && !showValue && (maxDate.season - 1) === index && year === maxDate.year),
            'diabled-button': (Number(year) > maxDateData.year) || ((Number(year) === (nowYear)) && (Number(nowSeason) < (index + 1))) || ((Number(year) === maxDateData.year) && (index + 1) > maxDateData.season)
          }"
          :disabled="(Number(year) > maxDateData.year) || ((Number(year) === (nowYear)) && (Number(nowSeason) < (index + 1))) || ((Number(year) === maxDateData.year) && (index + 1) > maxDateData.season)"
          @click="selectSeason(index)"
        >{{ item }}
        </el-button>
      </div>
      <!-- 年度 -->
      <div class="text item year" v-if="yearPicker">
        <el-button
          v-for="item in 9"
          :key="startYear + item - 1"
          type="text"
          size="medium"
          :class="{
            'active-button': (startYear + item - 1) === yearData,
            'diabled-button': Number(startYear + item - 1) > Number(maxDate.year ? maxDate.year : nowYear)
          }"
          :disabled="Number(startYear + item - 1) > Number(maxDate.year ? maxDate.year : nowYear)"
          @click="selectYear(startYear + item - 1)"
        >{{ startYear + item - 1 }}
        </el-button>
      </div>
    </el-card>
  </div>
</template>

js

<script>
import { getSeasonValue } from '@/utils/dateUtil'

export default {
  props: {
    mandatoryMaxDate: {
      type: Boolean,
      default: false,
    },
    valueArr: {
      default: () => ["01-03", "04-06", "07-09", "10-12"],
      type: Array,
    },
    getValue: {
      default: () => {
      },
      type: Function,
    },
    maxDate: {
      type: Object,
      default: () => {},
    },
    defaultValue: {
      default: "",
      type: String,
    },
    isShowDefaultValue: {
      type: Boolean,
      default: true,
    },
    isEdit: { // 是否可编辑
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      showSeason: false, // 控制【季度】弹框的显示与隐藏
      yearPicker: false, // 控制【年度】弹框的显示与隐藏
      seasonPicker: false, // 控制【季度】弹框的显示与隐藏
      season: "", // 季度
      year: new Date().getFullYear(), // 弹框上面的年份
      showValue: "", // 输入显示的值
      seasonArr: ["第一季度", "第二季度", "第三季度", "第四季度"], // 季度下拉框
      lineHeightClass: null, // 高亮显示标记
      yearData: "", // 年份的备份,主要是做季度是否可以选择或者禁选
      nowYear: new Date().getFullYear(), // 当前年份
      nowSeason: "", // 当前季度
      startYear: 0, // 开始年
      endYear: 0, // 结束年
      isHeightLineMax: false,
      maxDateData: { // 截止日期
        year: '',
        season: '',
      },
    };
  },
  created() {
    this.resetDefaultValue();
  },
  watch: {
    defaultValue(value) {
      if (!value) {
        this.resetDefaultValue();
      } else {
        const arr = value.split("-");
        this.year = arr[0];
        this.showValue = `${this.year}${arr[1]}季度`;
        this.$emit("showValue", this.year, arr[1]);
      }
    },
    maxDate: {
      handler(newVal) {
        if (!newVal) {
          const date = new Date()
          this.maxDateData.year = date.getFullYear()
          this.maxDateData.season = getSeasonValue().season
        } else {
          this.maxDateData = newVal
        }
      },
      deep: true,
      immediate: true,
    },
    mandatoryMaxDate: {
      handler(newVal) {
        this.isHeightLineMax = newVal
      },
      immediate: true,
    },
  },
  methods: {
    /** 打开弹窗 */
    openSeason() {
      if (!this.isEdit) {
        this.year = this.yearData;
        this.seasonPicker = true;
        this.yearPicker = false;
        this.showSeason = true;
      }
    },
    /** 季度往上翻 */
    prevSeason() {
      this.year = this.year * 1 - 1;
    },
    /** 季度往下翻 */
    nextSeason() {
      this.year = this.year * 1 + 1;
    },
    /** 选择季度事件 */
    selectSeason(i) {
      const that = this;
      that.lineHeightClass = i;
      that.season = i + 1;
      that.showSeason = false;
      that.getValue(`${this.year}-${this.season}`);

      this.yearData = this.year;
      this.showValue = `${this.year}${this.season}季度`;
      this.isHeightLineMax = false
      this.$emit("showValue", this.year, this.season);
    },
    /** 打开年度选择器 */
    openYear() {
      this.startYear = Math.floor(Number(this.year) / 10) * 10;
      this.endYear = this.startYear + 9;
      this.yearPicker = true;
      this.seasonPicker = false;
    },
    /** 年度往上翻 */
    prevYear() {
      this.startYear -= 10;
      this.endYear -= 10;
    },
    /** 年度往上翻 */
    nextYear() {
      this.startYear += 10;
      this.endYear += 10;
    },
    /** 年度选择事件 */
    selectYear(item) {
      this.year = item;
      this.yearPicker = false;
      this.seasonPicker = true;
    },
    /** 初始化 */
    resetDefaultValue() {
      const date = new Date();
      const month = date.getMonth();
      if (this.defaultValue) {
        const value = this.defaultValue;
        const arr = value.split("-");
        this.year = arr[0];
        this.yearData = arr[0];
        this.season = arr[1];
        this.lineHeightClass = this.season - 1;
        this.showValue = `${this.year}${this.season}季度`;
      } else if (!this.defaultValue && this.isShowDefaultValue) {
        this.year = date.getFullYear();
        this.yearData = date.getFullYear();
        this.season = Math.ceil((month + 1) / 3); // 获取季度
        this.lineHeightClass = this.season - 1;
        this.showValue = `${this.year}${this.season}季度`;
      } else {
        (this.isHeightLineMax && JSON.stringify(this.maxDate) !== '{}') ? this.year = this.maxDate.year : this.year = '';
        this.yearData = (this.isHeightLineMax && JSON.stringify(this.maxDate) !== '{}') ? this.year = this.maxDate.year : date.getFullYear();
        this.season = Math.ceil((month + 1) / 3); // 获取季度
        this.lineHeightClass = this.season - 1;
        this.showValue = "";
      }
      this.nowSeason = Math.ceil((month + 1) / 3); // 获取当前季度
      this.getValue(`${this.year}-${this.season}`);
    },
  },
};
</script>```
### scss

```css
<style lang="scss" scoped>
.default-season-picker {
  position: relative;

  .box-card {
    width: 100%;
    max-width: 322px;
    padding: 0 5px;
    margin-top: 10px;
    position: absolute;
    z-index: 9999;

    .text {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-around;
      text-align: center;

      .el-button {
        width: 40%;
        color: #606266;
        margin: 0;
        font-size: 12px;

        &:not(.diabled-button):hover {
          color: #2a76cd;
        }
      }

      .active-button {
        color: #2a76cd;
      }

      .diabled-button {
        color: #c0c4cc;
      }
    }

    .year {
      justify-content: normal;

      .el-button {
        width: 25%;
        padding: 25px 0;
      }
    }
  }
}
</style>

<style lang="scss">
.default-season-picker {
  .box-card {
    .el-card__header {
      padding: 10px 10px 0 10px;
    }

    .el-card__body {
      padding: 5px;
    }
  }

  .el-date-picker__header-label:hover,
  .el-picker-panel__icon-btn:hover {
    color: #2a76cd;
  }
}
</style>

getSeasonValue

/** 获取当前季度 */
export function getSeasonValue () {
  const date = new Date()
  const month = date.getMonth() + 1
  const season = Math.ceil(month / 3)
  const result = {
    year: date.getFullYear(), // 年度
    month,
    season,
    day: date.getDate(),
  }

  return result
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值