You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
7.6 KiB

<template>
<div class="date-picker">
<div class="header">
<div class="current-date year-selector" v-if="view === 'month'" >
1 month ago
<button @click="prevYear">&lt;</button>
<span @click="getMonYear">{{ currentYear !== selectedYear ? selectedYear : currentYear }}</span>
1 month ago
<button @click="nextYear">&gt;</button>
</div>
<div class="selectYear" v-if="view !== 'month'" >
<span class="year">{{view == 'monthTwo' ? '选择年份':'' }}</span>
</div>
<div class="controls">
1 month ago
<button v-if="!onlyYear" @click="toggleView('month')" :class="{ active: view !== 'year' }">月度</button>
<button @click="toggleView('year')" :class="{ active: view === 'year' }">年度</button>
</div>
</div>
<div class="selector" v-if="view === 'month'">
<div class="month-grid">
<button
v-for="month in months"
:key="month.value"
@click="selectMonth(month.value)"
:class="{ active: month.value === currentMonth && currentYear === selectedYear }"
>
{{ month.label }}
</button>
</div>
</div>
<div class="selector" v-if="view !== 'month'">
<div :class="[view == 'monthTwo' ? 'monthTwo-grid' :'','year-grid']">
<button
v-for="year in visibleYears"
:key="year"
@click="selectYear(year)"
:class="{
yearActive: year === currentYear,
current: year === new Date().getFullYear(),
}"
>
{{ year }}
</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'DatePicker',
props: {
modelValue: {
type: Date,
default: () => new Date()
},
view:{
type:String,
default:'month'
1 month ago
},
onlyYear:{
type:Boolean,
default:false
}
},
data() {
return {
// view: 'month', // 'month' or 'year monthTwo'
selectedYear: this.modelValue.getFullYear(),
currentMonth: this.modelValue.getMonth() + 1,
currentYear: this.modelValue.getFullYear(),
1 month ago
decadeStart: Math.floor(this.modelValue.getFullYear() / 10) * 10 - 6,
months: [
{ value: 1, label: '1月' },
{ value: 2, label: '2月' },
{ value: 3, label: '3月' },
{ value: 4, label: '4月' },
{ value: 5, label: '5月' },
{ value: 6, label: '6月' },
{ value: 7, label: '7月' },
{ value: 8, label: '8月' },
{ value: 9, label: '9月' },
{ value: 10, label: '10月' },
{ value: 11, label: '11月' },
{ value: 12, label: '12月' }
]
};
},
computed: {
decadeEnd() {
return this.decadeStart + 9;
},
visibleYears() {
const years = [];
for (let i = 0; i < 12; i++) {
years.push(this.decadeStart + i);
}
return years;
}
},
mounted(){
let selectedDate = new Date()
const oldDate = JSON.parse(localStorage.getItem('date'))
if(oldDate){
selectedDate = new Date(oldDate)
this.currentMonth = selectedDate.getMonth() + 1;
this.currentYear = selectedDate.getFullYear();
this.selectedYear = this.currentYear;
1 month ago
this.decadeStart = Math.floor(this.modelValue.getFullYear() / 10) * 10 - 6;
}else{
selectedDate = new Date()
}
},
beforeUnmount() {
// 移除监听
// this.$emit('update-count', 'month')
},
destroyed(){
1 month ago
// this.$emit('update-count', 'month')
console.log('destroyed====');
},
methods: {
1 month ago
getMonYear(){
this.$emit('update-count', 'monthTwo')
},
toggleView(viewType) {
this.$emit('update-count', viewType)
},
selectMonth(month) {
this.currentMonth = month;
this.currentYear = this.selectedYear;
this.$emit('update-count', 'month')
this.emitDate();
},
selectYear(year) {
this.selectedYear = year;
this.currentYear = this.selectedYear;
if(this.view == 'monthTwo'){
this.$emit('update-count', 'month')
}
this.emitDate();
},
prevYear() {
this.selectedYear--;
this.updateDecade();
},
nextYear() {
this.selectedYear++;
this.updateDecade();
},
prevDecade() {
this.decadeStart -= 10;
},
nextDecade() {
this.decadeStart += 10;
},
updateDecade() {
this.decadeStart = Math.floor(this.selectedYear / 10) * 10;
},
emitDate() {
const selectedDate = new Date(this.currentYear, this.currentMonth - 1, 1);
this.$emit('update:modelValue', selectedDate);
this.$emit('change', selectedDate);
}
},
watch: {
modelValue(newVal) {
let selectedDate = newVal
this.currentMonth = selectedDate.getMonth() + 1;
this.currentYear = selectedDate.getFullYear();
this.selectedYear = this.currentYear;
this.decadeStart = Math.floor(this.currentYear / 10) * 10;
}
}
};
</script>
<style scoped>
.date-picker {
font-family: Microsoft YaHei UI;
width: 300px;
/* border: 1px solid #ddd; */
border-radius: 4px;
padding: 10px 0 0 0;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); */
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 1px solid #F1F2F5;
letter-spacing: 0.08em;
color: #626573;
}
.current-date {
font-weight: bold;
}
.selectYear{
font-size: 14px;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0.08em;
color: #006AFF;
}
.controls{
border-radius: 4px;
background: #EAECF0;
box-sizing: border-box;
border: 1px solid #EAECF0;
padding: 3px 6px;
}
.selector{
}
.controls button {
background: none;
border: none;
padding: 1px 12px;
cursor: pointer;
}
.controls button.active {
background-color: #FFFFFF;
color: #006AFF;
/* border-color: #1890ff; */
}
.year-selector, .decade-selector {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.year-selector button, .decade-selector button {
background: none;
border: none;
cursor: pointer;
font-size: 16px;
}
.year-selector{
margin-bottom: 0;
}
.month-grid, .year-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
}
.month-grid button, .year-grid button {
font-family: Microsoft YaHei UI;
padding: 8px;
border: none;
display: flex;
align-items: center;
justify-content: center;
width: 48px;
background: none;
cursor: pointer;
border-radius: 20px;
color: #1E2226;
box-sizing: border-box;
}
.month-grid button:hover, .year-grid button:hover {
background-color: #F2F7FF;
}
.month-grid button.active, .year-grid button.active,.year-grid button.yearActive{
background-color: #006AFF;
color: white !important;
}
.monthTwo-grid button.current {
/* background-color: #006AFF !important;
color: white !important;
border-color: #1890ff !important; */
color: #fff;
}
.year-grid button.current{
/* font-weight: bold; */
color: #006AFF;
/* background-color: #F2F7FF; */
/* border-color: #1890ff; */
}
</style>