1.界面代码
html
<view class="o-calendar">
<view class="o-calendar-container" >
<view class="o-calendar-titlebar">
<view class="o-left_arrow" bind:tap="prevMonth">《</view>
{{year}}年{{month}}月
<view class="o-right_arrow" bind:tap="nextMonth">》</view>
<view class="o-btn-current-month" bind:tap="locateThisMonth">
<image class="o-btn-current-month-img" src="../../images/month.svg" />
</view>
</view>
<view class="o-calendar-weekdays">
<view wx:for="{{weekdays}}" wx:key="id" class="o-calendar-weekdays-item" >{{item}}</view>
</view>
<view class="o-calendar-weeks">
<block wx:for="{{calendarData}}" wx:key="index" >
<view class="o-calendar-week">
<block wx:for="{{item}}" wx:key="index">
<block wx:if="{{item===0}}">
<view class="o-calendar-item"></view>
</block>
<block wx:else>
<block wx:if="{{today && item===day}}">
<view class="o-calendar-day o-calendar-day-cur" bindtap="selectDate" data-value='{{item}}'>{{item}}</view>
</block>
<block wx:elif="{{item===selectedDay}}">
<view class="o-calendar-day o-calendar-day-selected" bindtap="selectDate" data-value='{{item}}'>{{item}}</view>
</block>
<block wx:else>
<view class="o-calendar-day" bindtap="selectDate" data-value='{{item}}'>{{item}}</view>
</block>
</block>
</block>
</view>
</block>
</view>
</view>
</view>
2.样式设置
html
page{
--o-calendar-background-color: #F1EBFE;
}
.o-calendar {
width: 100%;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 10rpx 30rpx;
}
.o-calendar-container{
padding: 0rpx 16rpx;
background-color: var(--o-calendar-background-color);
border-radius: 20rpx;
}
.o-calendar-titlebar{
display: flex;
justify-content: center;
align-items: center;
height: 50rpx;
font-size: 18px;
font-weight: bold;
padding-top: 20rpx;
}
.o-left_arrow {
width: 50rpx;
height: 50rpx;
position: absolute;
left: 180rpx;
}
.o-right_arrow {
width: 50rpx;
height: 50rpx;
position: absolute;
right: 180rpx;
}
.o-btn-current-month{
width: 50rpx;
height: 50rpx;
position: absolute;
right: 80rpx;
}
.o-btn-current-month-img{
width: 100%;
height: 100%;
}
.o-calendar-weekdays{
width: 100%;
height: 80rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.o-calendar-weekdays-item{
width: 60rpx;
line-height: 60rpx;
text-align: center;
margin: 5rpx;
}
.o-calendar-week{
width: 100%;
display: flex;
justify-content: space-between;
}
.o-calendar-item{
width: 60rpx;
height: 60rpx;
position: relative;
line-height: 60rpx;
margin: 5rpx;
}
.o-calendar-day {
width: 60rpx;
height: 60rpx;
position: relative;
display: flex;
line-height: 60rpx;
text-align: center;
justify-content: center;
margin: 5rpx;
border-radius: 50%;
cursor: pointer;
background-color: #fff;
}
.o-calendar-day-cur{
font-weight: bold;
color: #fff;
background-color: #F6AD77;
}
.o-calendar-day-selected{
font-weight: bold;
color: #fff;
background-color: rgb(7, 3, 1);
}
3.typescript脚本处理
TypeScript
/**
* 页面的初始数据
*/
data: {
year: 0, //记录年
month: 0, //记录月
day:0,//记录日
selectedDay:0,
calendarData: [], //记录日期
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
today:false,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad() {
this.renderCalendar();
},
renderCalendar: function () {
//获取当前日期
const currentDate:Date = new Date();
const currentYear:number = currentDate.getFullYear();
const currentMonth:number = currentDate.getMonth() + 1;
const currentDay:number = currentDate.getDate();
//获取年月日,未设置时默认当前日期
const year:number = this.data.year || currentYear;
const month:number = this.data.month || currentMonth;
const day:number = this.data.day || currentDay;
// 获取指定月份的总天数
const totalDays:number = new Date(year, month, 0).getDate();
// 获取指定月份第一天是星期几
let firstDayOfWeek:number = new Date(year, month - 1, 1).getDay();
//构建周期偏移实际数据
let total = firstDayOfWeek + totalDays;
// Math.ceil(total/7) -> 实际周期数
total = Math.ceil(total/7)*7;
// 定义存放日历数据的数组
const calendarData:number[][] = [];
// 初始化一个星期的数组
let week:number[] = [];
let num:number =0;
for(let i=1;i<=total;i+=7){
week = [];
for(let j=0;j<7;j++){
num = i-firstDayOfWeek +j
week.push(num<0 || num>totalDays? 0: num)
}
calendarData.push(week);
}
// 将生成的日历数据更新到页面数据中,使页面重新渲染
this.setData({
year: year,
month: month,
day:day,
calendarData: calendarData as any,
selectedDay:this.data.selectedDay,
today: year==currentYear && month==currentMonth && day==currentDay,
});
},
selectDate(event: any){
//console.log(event);
this.setData({
selectedDay: event.currentTarget.dataset.value,
});
},
prevMonth(event: any){
this.data.month -= 1;
if(this.data.month==0){
this.data.year -= 1;
this.data.month = 12;
}
this.data.selectedDay=0;
this.renderCalendar();
},
nextMonth(event: any){
this.data.month += 1;
if(this.data.month==13){
this.data.year += 1;
this.data.month = 1;
}
this.data.selectedDay=0;
this.renderCalendar();
},
locateThisMonth(event: any){
this.data.year=0;
this.data.month=0;
this.data.day=0;
this.data.selectedDay=0;
this.renderCalendar();
},