效果大概如下,样式自己修改,没怎么好好优化,部分ts代码copy过来的
html代码:
<div class="calender">
<div class="calender-name">
xxxx日历
</div>
<div class="calender-opt">
<div class="calender-opt-last" (click)="lastMonth()">上个月</div>
<div class="calender-opt-date">
<nz-month-picker
[(ngModel)]="date"
(ngModelChange)="onChangeMonth($event)"
nzPlaceHolder="Select month"
></nz-month-picker>
</div>
<div class="calender-opt-next" (click)="nextMonth()">下个月</div>
</div>
<div class="calender-item" *ngFor="let data of weektable.common.cn">{{data}}</div>
<div
class="calender-item"
*ngFor="let data of allDays"
[ngClass]="{
'calender-item-actived': data.selected,
'calender-item-currentMonth': data.isThisMonth
}"
>
<span style="color: #e1e1e1;" *ngIf="!data.isThisMonth">
{{data.dayNum}}
</span>
<span class="calender-item-thisMonth" (click)="activeDay(data.dayNum)" *ngIf="data.isThisMonth">
{{data.dayNum}}
</span>
</div>
</div>
css代码
.calender {
display: flex;
flex-wrap: wrap;
width: 420px;
&-name {
width: 100%;
height: 48px;
line-height: 48px;
text-align: center;
color: #fff;
background-color: #581B86;
}
&-opt {
height: 36px;
line-height: 36px;
width: 100%;
display: flex;
>div {
flex: 1;
}
&-last {
padding-left: 10px;
cursor: pointer;
}
&-date {
text-align: center;
}
&-next {
padding-right: 10px;
text-align: right;
cursor: pointer;
}
}
&-item {
width: 60px;
height: 40px;
// line-height: 40px;
text-align: center;
box-sizing: border-box;
border: 1px solid #e1e1e1;
&-actived {
// background-color: royalblue;
// color: #fff;
}
&-currentMonth {
background-color: #F3FFFF;
}
&-thisMonth {
cursor: pointer;
}
}
}
ts代码
public date = new Date();
public year = this.date.getFullYear();
public month = this.date.getMonth() + 1;
public currentMonth = this.date.getMonth() + 1;
public day = this.date.getDate();
public allDays: any[] = [];
public weektable = {
common: {
cn: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
cns: ['日', '一', '二', '三', '四', '五', '六'],
en: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
},
intl: {
cn: ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
cns: ['一', '二', '三', '四', '五', '六', '日'],
en: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
}
}
public ngOnInit(): void {
this.allDays = this.getMonthDaysArray(this.year, this.month, this.day);
console.log(this.allDays);
}
public formate(fmt, date) {
date = new Date(date).toString() === 'Invalid Date' ? new Date() : new Date(date);
const _rules = [{
rule: '[yY]{4}',
value: date.getFullYear()
}, {
rule: 'M+',
value: date.getMonth() + 1
}, {
rule: '[dD]+',
value: date.getDate()
}, {
rule: 'h+',
value: date.getHours()
}, {
rule: 'm+',
value: date.getMinutes()
}, {
rule: 's+',
value: date.getSeconds()
}, {
rule: 'ms{1,2}',
value: date.getMilliseconds()
}];
_rules.forEach((_r) => {
const rule = _r.rule, val = _r.value;
fmt = fmt.replace(new RegExp(rule), function ($1) {
const rLen = val.toString().length, fLen = $1.length;
return (fLen !== 2 || rLen >= fLen) ? val : ['00', val].join('').substr(rLen);
});
});
return fmt;
}
//修正年月
public fixedYM(year = this.year, month = this.month) {
if (+month === 0) {
year = +year - 1;
month = 12;
};
if (+month === 13) {
year = +year + 1;
month = 1;
};
return [year, month];
}
//获取某年某月有多少天
public getMonthDays(year, month) {
const YM = this.fixedYM(year, month);
return new Date(YM[0], YM[1], 0).getDate();
}
//返回某年某月某日是星期几
public getWeekday(year, month, day = this.day) {
const YM = this.fixedYM(year, month);
return new Date(YM[0], YM[1] - 1, day).getDay();
}
//获取某年某月的具体天数的排列顺序
public getMonthDaysArray(year = this.year, month = this.month, day) {
if (typeof day === 'undefined' && year === this.year && month === this.month) day = this.day;
let dayArrays = [];
const days = this.getMonthDays(year, month), preDays = this.getMonthDays(year, month - 1);
const thisMonthFirstDayInWeek = this.getWeekday(year, month, 1), thisMonthLastDayInWeek = this.getWeekday(year, month, days);
const thisMonthAllDays = thisMonthFirstDayInWeek + days + 6 - thisMonthLastDayInWeek;
//上月在当月日历面板中的排列
for (let i = 0; i < thisMonthFirstDayInWeek; i++) {
dayArrays.push({
dayNum: (preDays - thisMonthFirstDayInWeek + i + 1),
weekDay: this.weektable.common.cn[i]
})
}
//当月日历面板中的排列
for (let i = 1; i <= days; i++) {
const weekDayFlag = (thisMonthFirstDayInWeek + i - 1) % 7
dayArrays.push({
dayNum: i,
weekDay: this.weektable.common.cn[weekDayFlag],
selected: i === +day,
isThisMonth: true
})
};
//下月在当月日历面板中的排列
for (let i = 1; i <= (6 - thisMonthLastDayInWeek); i++) {
const weekDayFlag = (thisMonthFirstDayInWeek + days + i - 1) % 7
dayArrays.push({
dayNum: i,
weekDay: this.weektable.common.cn[weekDayFlag]
})
};
return dayArrays;
}
public lastMonth() {
this.month--;
if (this.month === 0) {
this.month = 12;
this.year --;
}
this.allDays = this.getMonthDaysArray(this.year, this.month, this.day);
}
public nextMonth() {
this.month++;
if (this.month === 13) {
this.month = 1;
this.year++;
}
this.allDays = this.getMonthDaysArray(this.year, this.month, this.day);
}
public onChangeMonth(date: any) {
this.year = date.getFullYear();
this.month = date.getMonth() + 1;
this.currentMonth = date.getMonth() + 1;
this.day = date.getDate();
this.allDays = this.getMonthDaysArray(this.year, this.month, this.day);
}
public activeDay(day: number) {
this.allDays = this.getMonthDaysArray(this.year, this.month, day);
}