季度选择下拉框
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
}