效果图:
未来时间禁选(可选的)
回传给父组件的值:
季度选择器组件代码:
<template>
<el-form>
<el-form-item>
<mark
class="mark"
v-show="showSeason"
@click.stop="showSeason = false"
></mark>
<el-input
placeholder="请选择季度"
readonly
v-model="showValue"
size="small"
@focus="showSeason = true"
>
<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="year-btn">
<button
type="button"
aria-label="前一年"
class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"
@click="prev"
></button>
<span role="button">{{ year }}年</span>
<button
type="button"
aria-label="后一年"
@click="next"
class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right"
></button>
</div>
<div class="season-list">
<div
v-for="btn in buttonList"
:key="year + '-' + btn"
:class="{
'season-item': true,
'is-active': showValue === `${year}年第${['', '一', '二', '三', '四'][btn]}季度`,
'is-disabled': getDisable(year, btn)
}"
@click="selectSeason(btn)"
>
{{ `第${['', '一', '二', '三', '四'][btn]}季度` }}
</div>
</div>
</el-card>
</el-form-item>
</el-form>
</template>
<script>
export default {
name: 'CustomQuarterPicker',
props: {
defaultValue: {
default: '', // '2024年第二季度'
type: String,
},
disabledFeature: { // 未来时间禁选
type: Boolean,
default: false,
}
},
data() {
this.buttonList = [1, 2, 3, 4]
return {
showSeason: false,
season: '',
year: new Date().getFullYear(),
showValue: '',
nowObj: {}
}
},
created() {
const now = new Date()
let nowObj ={
year: now.getFullYear(),
season: (now.getMonth() + 1)
}
if(nowObj.season <= 3) {
nowObj.season = 1
} else if(nowObj.season <= 6) {
nowObj.season = 2
} else if(nowObj.season <= 9) {
nowObj.season = 3
} else {
nowObj.season = 4
}
this.nowObj = nowObj
},
watch: {
defaultValue: {
handler(value) {
if (value) {
this.year = value.substr(0, 4)
this.showValue = value
}
},
immediate: true,
},
},
methods: {
prev() {
this.year = +this.year - 1
},
next() {
this.year = +this.year + 1
},
selectSeason(num) {
if(this.getDisable(this.year, num)) return
this.season = num
this.showSeason = false
this.showValue = `${this.year}年第${['', '一', '二', '三', '四'][num]}季度`
this.sendMsg()
},
getDisable(year, btn) {
return this.disabledFeature && (
year > this.nowObj.year ||
(year == this.nowObj.year && btn > this.nowObj.season)
)
},
sendMsg() {
const dateArr = [
['01-01', '03-31'],
['04-01', '06-30'],
['07-01', '09-30'],
['10-01', '12-31'],
]
const result = {
value: this.showValue,
year: this.year,
season: this.season,
dateRange: [
`${this.year}-${dateArr[this.season - 1][0]}`,
`${this.year}-${dateArr[this.season - 1][1]}`,
],
dateTimeRange: [
`${this.year}-${dateArr[this.season - 1][0]} 00:00:00`,
`${this.year}-${dateArr[this.season - 1][1]} 23:59:59`,
],
}
this.$emit('func', result)
},
},
}
</script>
<style lang="scss" scoped>
.el-form-item {
margin-bottom: 0;
height: 32px;
}
::v-deep .el-form-item__content {
height: 32px;
line-height: 32px;
}
.box-card {
width: 322px;
padding: 0;
margin-top: 10px;
position: absolute;
z-index: 9999;
}
::v-deep .el-card__header {
height: 30px;
padding: 0 0 12px 0;
box-sizing: content-box;
margin: 12px 12px 0 12px;
}
::v-deep .el-card__body {
padding: 10px 0;
}
.el-input {
width: 220px !important;
height: 32px;
}
.mark {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0);
z-index: 999;
}
.year-btn {
text-align: center;
padding: 0;
}
.season-list {
.season-item {
display: inline-block;
width: 50%;
color: #606266;
text-align: center;
cursor: pointer;
&:hover {
color: #409eff;
}
&.is-active {
color: #409eff;
border-color: rgba(255, 255, 255, 0); // 隐藏边框
}
&.is-disabled {
// background-color: #F5F7FA;
color: #C0C4CC;
cursor: no-drop;
}
}
}
</style>
父组件使用案例
<customQuarterPicker v-show="dateType === 'quarter'" @func="getMsgQuarter" :defaultValue="dateValueQuarter" />
getMsgQuarter(val) {
console.log('val----', val)
this.dateValueQuarter = val?.value || ''
},