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>