简介:
最近有个需求需要按照年月周日来获取时间,具体如图
本人也是新手,所以对我来说其中比较困难的是按周查询(其他的可以看element官网即可),由于element设计的周不符合业务需求,所以也找了一些来参考借鉴。完成后结果具体如图所示。
代码实现(如有逻辑错误,可以在评论区指出)
<template>
<div>
<div>
<el-row>
<el-col :span="4">
<el-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="12" v-if="value != 'week'">
<el-date-picker
v-model="timeObj.showStartTime"
:type="formatObj.type"
:format="formatObj.format"
:value-format="formatObj.valueFormat"
placeholder="选择日期">
</el-date-picker>
至
<el-date-picker
v-model="timeObj.showEndTime"
:type="formatObj.type"
:format="formatObj.format"
:value-format="formatObj.valueFormat"
placeholder="选择日期">
</el-date-picker>
</el-col>
<el-col :span="16" v-else>
<div class="jidudatepicker">
<span style="width: 322px">
<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: 322px;height: 0.36rem;line-height: 0.36rem;"
@focus="add"
>
<i slot="prefix" class="el-input__icon el-icon-date"></i>
</el-input>
<el-card
class="box-card"
style="width:322px;padding: 0 3px 20px;margin-top:10px;position:fixed;z-index:9999"
v-if="showSeason"
>
<div slot="header" class="firstBtn">
<button
type="button"
aria-label="前一年"
class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"
@click="prev"
></button>
<button
type="button"
aria-label="前一月"
class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-arrow-left"
@click="prevMonth"
></button>
<span role="button" class="el-date-picker__header-label">{{year}}年{{month}}月</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>
<button
type="button"
aria-label="后一年"
@click="nextMonth"
class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-arrow-right"
></button>
</div>
<div class="text container">
<!-- 如下,绑定class,disabled为禁止选择的时间的设置 -->
<el-button
type="text"
size="medium"
style="width:47%;color: #606266;float:left;"
@click="selectSeason(0)"
>第一周</el-button>
<el-button
type="text"
size="medium"
style="float:right;width:47%;color: #606266;"
@click="selectSeason(1)"
>第二周</el-button>
</div>
<div class="item container" style="text-align:center;">
<el-button
type="text"
size="medium"
style="width:47%;color: #606266;float:left;"
@click="selectSeason(2)"
>第三周</el-button>
<el-button
type="text"
size="medium"
style="float:right;width:47%;color: #606266;"
@click="selectSeason(3)"
>第四周</el-button>
</div>
<div class="item container" style="text-align:center;"
v-if="this.countWeekInMonth > 5 || this.countWeekInMonth == 5">
<el-button
type="text"
size="medium"
style="width:47%;color: #606266;float:left;"
@click="selectSeason(4)"
>第五周</el-button>
<el-button
v-if="this.countWeekInMonth > 5"
type="text"
size="medium"
style="float:right;width:47%;color: #606266;"
@click="selectSeason(5)"
>第六周</el-button>
</div>
</el-card>
</span>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
export default {
name: "index",
data() {
return {
value:'day',
options:[
{
value:"year",
label:'按年',
},
{
value:"month",
label:'按月',
},
{
value:"week",
label:'按周',
},
{
value:"day",
label:'按日',
},
],
timeObj:{
showStartTime:'',
showEndTime:'',
},
formatObj:{
type:'date',
format:'yyyy-MM-dd',
valueFormat:'yyyy-MM-dd',
},
countWeekInMonth: 0,
showSeason: false,
season: "",
year: new Date().getFullYear(), // input显示时间,会随着用户操作改变
month: new Date().getMonth() + 1, // 当前月份
showValue: "",
};
},
created() {
// }
},
mounted() {
},
watch: {
value(newData){
this.timeObj={
showStartTime:'',
showEndTime:'',
}
if(newData=='year'){
this.formatObj={
type:'year',
format:'yyyy',
valueFormat:'yyyy-MM-dd',
}
}else if(newData=='month'){
this.formatObj={
type:'month',
format:'yyyy-MM',
valueFormat:'yyyy-MM-dd',
}
}else if(newData=='week'){
this.countWeekInMonth = this.weekInMonthCount(new Date())
}else if(newData=='day'){
this.formatObj={
type:'date',
format:'yyyy-MM-dd',
valueFormat:'yyyy-MM-dd',
}
}
},
'timeObj.showStartTime':{
handler: function(val){
// console.log('监听nameList: ',val);
this.compareTwoValue()
}
},
'timeObj.showEndTime':{
handler: function(val) {
// console.log(val);
this.compareTwoValue()
}
},
},
methods: {
formatTwoValue(){
let endTime = new Date(this.timeObj.showEndTime)
if(this.value == 'year'){
endTime = new Date(endTime.getFullYear()+'-12-31')
}else if (this.value == 'month'){
endTime = new Date(endTime.getFullYear(),endTime.getMonth()+1,0)
}
let obj = {
start:this.timeObj.showStartTime,
end:this.formatDate(endTime)
}
return obj
},
//比较两个值的大小
compareTwoValue(){
if(this.timeObj.showEndTime == '' || this.timeObj.showStartTime == '' || this.timeObj.showStartTime == null || this.timeObj.showEndTime == null){
return;
}
var obj = this.formatTwoValue();
if(obj.end < obj.start){
this.$message.warning("开始时间大于结束时间")
return;
}
console.log(obj)
this.$emit("chooseSeason", obj); // 每次选择时间都将当前选择时间发送到父组件
},
/**
* 日期Date转String
* @param date
* @returns {string}
*/
formatDate (date) {
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? '0' + m : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
return y + '-' + m + '-' + d;
},
add() {
this.showSeason = true
},
//年份减一
prev() {
this.year = this.year * 1 - 1;
console.log(this.year)
console.log(this.month)
this.countWeekInMonth = this.weekInMonthCount(new Date(this.year, this.month - 1, 1))
},
//月份减一
prevMonth() {
if (this.month == 1) {
this.year = this.year * 1 - 1;
this.month = 12;
} else {
this.month = this.month * 1 - 1;
}
console.log(this.year)
console.log(this.month)
this.countWeekInMonth = this.weekInMonthCount(new Date(this.year, this.month - 1, 1))
},
//月份加一
next() {
this.year = this.year * 1 + 1;
console.log(this.year)
console.log(this.month)
this.countWeekInMonth = this.weekInMonthCount(new Date(this.year, this.month - 1, 1))
},
//年份加一
nextMonth() {
if (this.month == 12) {
this.year = this.year * 1 + 1;
this.month = 1;
} else {
this.month = this.month * 1 + 1;
}
console.log(this.year)
console.log(this.month)
this.countWeekInMonth = this.weekInMonthCount(new Date(this.year, this.month - 1, 1))
},
// 返回第几周的开始和结束时间
selectSeason(i) {
let that = this;
that.season = i + 1;
that.showSeason = false;
this.showValue = `${this.year} 年 ${this.month} 月 ${this.season} 周`;
var date = new Date(this.year, this.month, 0)
var totalDayAMonth = date.getDate();
date.setDate(1);
if (this.season == 1) {
var start = new Date(this.year, this.month - 1, 1)
var day = date.getDay()
if (day == 0) {
day = 7
}
var end = new Date(this.year, this.month - 1, 7 - day + 1)
} else if (this.season == 2) {
var day = date.getDay()
if (day == 0) {
day = 7
}
var start = new Date(this.year, this.month - 1, 7 - day + 2)
var end = new Date(this.year, this.month - 1, 7 - day + 8)
} else if (this.season == 3) {
var day = date.getDay()
if (day == 0) {
day = 7
}
var start = new Date(this.year, this.month - 1, 7 - day + 9)
var end = new Date(this.year, this.month - 1, 7 - day + 15)
} else if (this.season == 4) {
var day = date.getDay()
if (day == 0) {
day = 7
}
var start = new Date(this.year, this.month - 1, 7 - day + 16)
var end = new Date(this.year, this.month - 1, 7 - day + 22)
} else if (this.season == 5 && totalDayAMonth != 28) {
if (this.countWeekInMonth == 5) {
var day = date.getDay()
if (day == 0) {
day = 7
}
var start = new Date(this.year, this.month - 1, 7 - day + 23)
var end = new Date(this.year, this.month, 0)
} else {
var day = date.getDay()
if (day == 0) {
day = 7
}
var start = new Date(this.year, this.month - 1, 7 - day + 23)
day = new Date(this.year, this.month - 1, 29).getDay()
if (day == 0) {
var end = new Date(this.year, this.month - 1, 29)
} else if (day == 6) {
var end = new Date(this.year, this.month - 1, 30)
}
}
} else if (this.season == 5 && totalDayAMonth == 28) {
var day = date.getDay()
if (day == 0) {
day = 7
}
var start = new Date(this.year, this.month - 1, 7 - day + 23)
var end = new Date(this.year, this.month, 0)
} else if (this.season == 6) {
if (new Date(this.year, this.month - 1, 29).getDay() == 0) {
var start = new Date(this.year, this.month - 1, 30)
var end = new Date(this.year, this.month, 0)
} else if (new Date(this.year, this.month - 1, 30).getDay() == 0) {
var start = new Date(this.year, this.month - 1, 31)
var end = new Date(this.year, this.month - 1, 31)
}
}
var returnTime = {
start:this.formatDate(start),
end:this.formatDate(end)
}
console.log(returnTime)
that.$emit("chooseSeason", returnTime); // 每次选择时间都将当前选择时间发送到父组件
},
/**
* 计算某年某月有几周
* @returns {number}
*/
weekInMonthCount(dateTime) {
var date = dateTime;
console.log(date)
date.setMonth(date.getMonth() + 1);
date.setDate(0);
// 计算一个月有几天
var monthDay = date.getDate()
date.setDate(1)
// 去除28号的特殊情况
if (monthDay !== 28) {
// 判断一号是否为周日
if (date.getDay() === 0) {
var lastDay = monthDay - 1
if (lastDay % 7 > 0) {
var weekCount = lastDay / 7 + 2
} else {
var weekCount = lastDay / 7 + 1
}
} else if (date.getDay() === 6) { // 判断一号位周六
var lastDay = monthDay - 2
if (lastDay % 7 > 0) {
var weekCount = lastDay / 7 + 2
} else {
var weekCount = lastDay / 7 + 1
}
} else {
if (monthDay % 7 > 0) {
var weekCount = monthDay / 7 + 1
} else {
var weekCount = monthDay / 7
}
}
weekCount = weekCount.toFixed(0)
} else {
if (date.getDay() === 1) {
var weekCount = "4"
} else {
var weekCount = "5"
}
}
return weekCount; // 计算本月有几周
},
}
}
</script>
<style lang="scss" scoped>
.jidudatepicker {
display: inline;
.firstBtn {
height: 30px;
line-height: 34px;
width: 300px;
text-align: center;
}
.text {
text-align: center;
margin: 15px 0 10px;
}
.item {
text-align: center;
}
}
.colorDis {
color: #999 !important;
}
</style>
<style lang="scss">
.jidudatepicker {
.el-card__header {
padding: 12px;
}
}
</style>
按周的逻辑
比如如今是2023年1月份。默认以周一为一周的开始,我的需求逻辑为本周有6周。
第一周返回日期:01日-01日
第六周返回日期:30日-31日
借鉴参考
elementUI 日 周 月 季 年 时间选择控件封装_丿刘先森的博客-CSDN博客_日 周 月 季 年 时间选择控件
vue + element-ui 季度选择器组件 el-quarter-picker_JeromeLLR的博客-CSDN博客_vue季度控件