elementUI实现月份范围选择

elementUI实现月份范围选择
效果:
在这里插入图片描述

<template>
  <div class="selectMonthBoxSquare" id="boxArea">
    <el-date-picker
      v-model="optTimes"
      @focus="showBox = true"
      popper-class="mySelectMonth"
      type="monthrange"
      range-separator=""
      start-placeholder="开始月份"
      end-placeholder="结束月份"
    ></el-date-picker>
    <!-- 年份月份选择弹框 -->
    <div class="selectContentBox" v-if="showBox">
      <div class="contentArea">
        <!-- 年份 -->
        <div class="yearBox">
          <i
            class="el-icon-d-arrow-left"
            v-if="curIndex == DateList.length - 1"
            style="color:#ddd;cursor: not-allowed;"
          ></i>
          <i
            class="el-icon-d-arrow-left"
            style="cursor:pointer;"
            title="上一年"
            v-else
            @click="reduceYear"
          ></i>
          <span>{{OneY}}年</span>
          <i
            class="el-icon-d-arrow-right"
            v-if="curIndex == 0"
            style="color:#ddd;cursor: not-allowed;"
          ></i>
          <i
            class="el-icon-d-arrow-right"
            style="cursor:pointer;"
            title="下一年"
            v-else
            @click="addYear"
          ></i>
        </div>
        <!-- 月份 -->
        <div style="padding:20px;">
          <el-checkbox-group v-model="optTime[curIndex].queryTime" @change="onChange">
            <el-checkbox
              class="onSelect"
              v-for="(item,index) in DateList[curIndex].queryTime"
              :key="index"
              :style="setMonthStyle(item,DateList[curIndex].TimeYear)"
              :disabled="isDisabled(`${DateList[curIndex].TimeYear}-${(item<=9)?`0${item}`:item}`)"
              :label="`${DateList[curIndex].TimeYear}-${(item<=9)?`0${item}`:item}`"
            >{{monthMap[item]}}月</el-checkbox>
          </el-checkbox-group>
        </div>
      </div>
    </div>
  </div>
</template>
`<script>
export default {
  name: "selectMonth",
  watch: {
    optTimes(val) {
      if (!val) {
        for (let i in this.optTime) {
          this.optTime[i].queryTime = [];
        }
        this.selectYear = null;
      }
      if (val && val.length > 2) {
        this.optTimes = [];
        for (let i in this.optTime) {
          if (this.optTime[i].TimeYear == this.OneY) {
            this.optTime[i].queryTime = [val[2]];
          } else {
            this.optTime[i].queryTime = [];
            this.selectYear = [];
          }
        }
      }
      if (val && val.length == 2) {
        if (Number(val[0].split("-")[1]) > Number(val[1].split("-")[1])) {
          val.reverse();
        }
        this.selectYear = Number(val[0].split("-")[0]);
        setTimeout(() => {
          // 模拟elementUI中月份选择的效果
          this.showBox = false;
        }, 200);
      }
    }
  },
  data() {
    return {
      selectYear: null,
      DateList: [], // 年份月份数组
      optTime: [], // 月份选中结果数组
      OneY: "", // 当前年份
      curIndex: 50, // 当前年份下标值
      optTimes: [], // 点击月份时的所有选中结果
      showBox: false, // 是否显示月份选择弹框
      monthMap: {
        // 月份显示为中文
        "1": "一",
        "2": "二",
        "3": "三",
        "4": "四",
        "5": "五",
        "6": "六",
        "7": "七",
        "8": "八",
        "9": "九",
        "10": "十",
        "11": "十一",
        "12": "十二"
      }
    };
  },
  created() {
    this.init();
  },
  mounted() {
    //点击弹框外的任意位置关闭区域弹窗
    document.addEventListener("click", e => {
      //获取弹窗对象
      const boxArea = document.getElementById("boxArea");
      //判断弹窗对象中是否包含点击对象
      if (boxArea && !boxArea.contains(e.target)) {
        // 关闭弹框
        this.showBox = false;
      }
    });
  },
  methods: {
    // 设置选中月份区间的样式
    setMonthStyle(item, year) {
      if (
        this.optTimes &&
        this.optTimes.length == 2 &&
        year == this.selectYear
      ) {
        let num1 = Number(this.optTimes[0].split("-")[1]);
        let num2 = Number(this.optTimes[1].split("-")[1]);
        if (num1 < num2) {
          if (item > num1 && item < num2) {
            return { background: "#f2f6fc" };
          } else if (item == num1) {
            return {
              borderTopLeftRadius: "24px",
              borderBottomLeftRadius: "24px",
              background: "#f2f6fc"
            };
          } else if (item == num2) {
            return {
              borderTopRightRadius: "24px",
              borderBottomRightRadius: "24px",
              background: "#f2f6fc"
            };
          }
        } else {
          if (item < num1 && item > num2) {
            return { background: "#f2f6fc" };
          } else if (item == num2) {
            return {
              borderTopLeftRadius: "24px",
              borderBottomLeftRadius: "24px",
              background: "#f2f6fc"
            };
          } else if (item == num1) {
            return {
              borderTopRightRadius: "24px",
              borderBottomRightRadius: "24px",
              background: "#f2f6fc"
            };
          }
        }
      }
    },
    // 控制月份禁用状态
    isDisabled(val) {
      let year = new Date().getFullYear();
      if (year != this.OneY) {
        return true;
      } else {
        return false;
      }
    },
    // 初始化数据,获取前后50年,然后循环 每一年里面都有12个月的 得到数组 opTime 和 DateList
    init() {
      const _this = this;
      let _opt = [];
      let _optTime = [];
      let arr = new Array(12);
      let optDate = this.getDateList();
      optDate.map((item, index) => {
        // 月份选择时el-checkbox-group绑定的值
        _optTime[index] = {
          TimeYear: item,
          queryTime: []
        };
        // 给每一年份设置12个月份,el-checkbox初始化显示时使用
        _opt[index] = {
          TimeYear: item,
          queryTime: []
        };
        for (let i = 1; i <= arr.length; i++) {
          _opt[index].queryTime.push(i);
        }
      });
      _this.optTime = _optTime;
      _this.DateList = _opt;
    },
    // 获取近前后50年年份列表,倒序排列,最新一年在最前面
    getDateList() {
      let Dates = new Date();
      let year = Dates.getFullYear();
      this.OneY = year;
      let optDate = [];
      for (let i = year - 50; i <= year + 50; i++) {
        optDate.push(i);
      }
      return optDate.reverse();
    },
    // 左上角年份减少
    reduceYear() {
      const _this = this;
      // 如果已经是最后一年了,则年份不能再减少了
      if (_this.curIndex == _this.DateList.length - 1) return;
      // 当前下标值+1,根据下标值获取年份值
      _this.curIndex = _this.curIndex + 1;
      _this.OneY = _this.DateList[_this.curIndex].TimeYear;
    },
    // 右上角年份增加
    addYear() {
      const _this = this;
      // 如果已经是当前年份了,则年份不能再增加了
      if (_this.curIndex == 0) return;
      // 当前下标值-1,根据下标值获取年份值
      _this.curIndex = _this.curIndex - 1;
      _this.OneY = _this.DateList[_this.curIndex].TimeYear;
    },
    // 选择月份
    onChange() {
      const _this = this;
      // 遍历optTime中已选择的月份,将已选结果塞到optTimes数组中
      let _opt = _this.optTime;
      let arr = [];
      for (let item in _opt) {
        if (_opt[item].queryTime.length > 0)
          _opt[item].queryTime.filter(v => {
            arr.push(v);
          });
      }
      _this.optTimes = arr;
    }
  }
};
</script>
```css
<style>
.mySelectMonth {
  display: none !important;
  width: 0px !important;
  height: 0px !important;
}
</style>
<style scoped>
.selectMonthBoxSquare {
  margin-top: 10px;
  width: 250px;
}
.yearBox {
  padding: 15px 0;
  border-bottom: 1px solid #e5e5e5;
  display: flex;
  justify-content: space-around;
}
.inputStyle {
  width: 250px;
}
.clearIconStyle {
  display: none;
}
.inputStyle:hover .clearIconStyle {
  display: block;
}
.selectContentBox {
  position: absolute;
  top: 50px;
  left: 0;
  z-index: 2021;
  background: #ffffff;
  border: 1px solid #e5e5e5;
  border-radius: 3px;
}
.contentArea {
  width: 330px;
}
.onSelect {
  width: 25% !important;
  padding: 6px 0 !important;
  height: 36px;
  line-height: 36px;
  margin: 8px 0px;
}
.selectMonthBoxSquare >>> .el-checkbox__input {
  display: none !important;
}
.selectMonthBoxSquare >>> .el-checkbox__label {
  padding-left: 0px !important;
}
.selectMonthBoxSquare >>> .el-checkbox__label:hover {
  color: #409eff;
}
.selectMonthBoxSquare >>> .is-checked > .el-checkbox__label {
  width: 60px;
  height: 36px;
  display: block;
  line-height: 36px;
  margin: 0 auto;
  border-radius: 18px;
  color: #fff;
  background-color: #409eff;
}
.selectBox {
  width: 100px;
}
.selectMonthBoxSquare >>> input {
  height: 25px;
  line-height: 25px;
}
.selectMonthBoxSquare >>> .el-input .el-input__icon {
  line-height: 25px;
}
.selectMonthBoxSquare >>> .el-button--mini {
  padding: 5px 15px;
  font-size: 12px;
  border-radius: 3px;
}
.buttonBox {
  border-top: 1px solid #e5e5e5;
  padding: 10px 10px 10px 0;
}
</style>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值