微信小程序 typescript 开发日历界面

发布于:2024-07-04 ⋅ 阅读:(14) ⋅ 点赞:(0)

1.界面代码

<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.样式设置

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脚本处理

  /**
   * 页面的初始数据
   */
  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();
  },

4.效果