小程序 - 日历组件

本文介绍了如何在小程序中创建一个日历组件,包括显示当前月份日历、切换上下月份及返回今天。主要利用JavaScript的Date对象来获取年月日信息、计算每月天数和星期。文章提供了一个实现该功能的小程序项目的.wxml、.css和.js代码片段,并提供了代码下载链接。
摘要由CSDN通过智能技术生成

在小程序中完成日历选择日期的功能(显示当前月份日历、上下月份日历查询、回到今天),效果如下

涉及到的知识点也不多,使用JavaScript提供的Date对象及其方法

1.获取当前年、月、日数据

let year  = date.getFullYear()
let month = date.getMonth()    // 月份的区间为 0-11
let day   = date.getDate()

2.获取当前月份总天数。较为简单的方法是将12个月分别对应的天数存入数组中,再根据平年闰年判断二月份是28天还是29天。这里推荐一种更为简便的方法,在new Date()构造函数中,将当前月份+1,day设为0,getDate()获取的就是当前月份的总天数

// 月份总天数
let days = new Date(year, month + 1, 0).getDate()

3.获取当前月份的一号是星期几。星期的区间 0 - 6,0代表星期日

let whichDay = new Date(year, month, 1).getDay()

4.将当前月份总天数存入数组。这里以星期天的起点,如果当前月份的第一天不是星期天,数组前面需要补上空元素

// 存放日期数组
let dayList = []

// 补空
for (let j = 0; j < whichDay; j++) {
  let obj = { 'day': '' };
  dayList.push(obj)
}

for (let i = 1; i <= days; i++) {
  let obj = {
    'day': i,
  }

  dayList.push(obj)
}

5.月份切换。同样使用new Date()构造函数,只需传入year、month+/-1。例如2019年1月获取上一个月的数据,new Date(2019, 0-1);2019年1月获取下一个月的数据,new Date(2019, 0+1);

let date      = new Date(year, month + flag) // flag代表增加或减少的月份
let new_year  = date.getFullYear()
let new_month = date.getMonth()

以下是小程序项目个文件代码。打包文件下载地址:小程序日历组件

.wxml

<!-- 日期选择 tab -->
<view class="date-select bordertop" wx:if="{{yanse_column == 0}}">
  <view class="date-box">
    <view class="date" catchtap="dayShow">
      <text class="day">{{day}} </text>/ {{_year}}-{{_month + 1}}
    </view>
    <image class="date-icon" src="../../assets/icon/icon_jt_pre@2x.png" mode="aspectFill"></image>
    <view class="today" catchtap="todayDate">今天</view>
  </view>
</view>
<!-- 日期选择 -->
<view class="date-wrap {{dayShow ? 'date-wrap-active':''}}">
  <view class="dw-top">
    <view class="dw-year-month">{{year_month}}</view>
    <image class="dw-arrow-left" src="../../assets/icon/icon_xzyf_left@2x.png" mode="aspectFill"></image>
    <image class="dw-arrow-right" src="../../assets/icon/icon_xzyf_right@2x.png" mode="aspectFill"></image>
    <view class="dw-btn dw-btn-left" catchtap="switchMonth" data-index="-1"></view>
    <view class="dw-btn dw-btn-right" catchtap="switchMonth" data-index="1"></view>
  </view>
  <view class="dw-week">
    <view>日</view>
    <view>一</view>
    <view>二</view>
    <view>三</view>
    <view>四</view>
    <view>五</view>
    <view>六</view>
  </view>
  <!-- 日期 dl-today -->
  <view class="date-list">
    <view class="dl-li">
      <block wx:for="{{dayList}}" wx:key="{{index}}">
        <view
          class="dl-item {{item['class']}}"
          data-day="{{item['day']}}"
          data-clazz="{{item['class']}}"
          catchtap="selectDay"
        >
          {{item['day']}}
        </view>
      </block>
    </view>
  </view>
</view>
<!-- 阴影 -->
<view class="date-wrap-shadow" wx:if="{{dayShow}}" catchtap="close_dayShow"></view>

.css

page {
  background: #f1f1f1;
}

/* start 日期选择 */
.date-select {
  width: 100%;
  height: 120rpx;
  font-size: 0;
  background: #ffffff;
  box-sizing: border-box;
  z-index: 20;
}

.date-box {
  position: relative;
}

.date {
  display: inline-block;
  margin-top: 24rpx;
  margin-left: 30rpx;
  font-family: PingFangSC-Medium;
  font-size: 24rpx;
  color: #000000;
  border-right: 4rpx solid transparent;
}

.day {
  font-family: PingFangSC-Medium;
  font-size: 60rpx;
}

.today {
  position: absolute;
  top: 44rpx;
  right: 30rpx;
  font-family: PingFangSC-Regular;
  font-size: 30rpx;
  color: #808080;
}

.date-icon {
  display: inline-block;
  width: 19rpx;
  height: 16rpx;
}

.date-wrap {
  position: fixed;
  width: 100%;
  top: -1000rpx;
  background: #ffffff;
  transition: top 0.3s ease;
  z-index: 10;
}

.date-wrap-active {
  top: 120rpx;
}

.dw-top {
  position: relative;
  width: 100%;
  height: 88rpx;
}

.dw-year-month {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  height: 88rpx;
  line-height: 88rpx;
  font-family: PingFangSC-Regular;
  font-size: 30rpx;
  color: #1D1D1D;
}

.dw-top > image {
  position: absolute;
  top: 32rpx;
  display: block;
  width: 22rpx;
  height: 22rpx;
}

.dw-arrow-left {
  left: 120rpx;
}

.dw-arrow-right {
  right: 120rpx;
}

.dw-btn {
  position: absolute;
  top: 0;
  width: 100rpx;
  height: 88rpx;
}

.dw-btn-left {
  left: 85rpx;
}

.dw-btn-right {
  right: 85rpx;
}

.dw-week {
  padding: 0 30rpx;
  width: 100%;
  height: 60rpx;
  line-height: 60rpx;
  font-family: PingFangSC-Regular;
  font-size: 24rpx;
  color: #808080;
  box-sizing: border-box;
}

.dw-week > view {
  display: inline-block;
  vertical-align: top;
  margin-right: 35rpx;
  max-width: 68rpx;
  width: 68rpx;
  text-align: center;
}

.dw-week > view:last-child {
  margin-right: 0;
}

.dl-li {
  padding: 0rpx 30rpx 10rpx;
  width: 100%;
  font-family: PingFangSC-Regular;
  font-size: 30rpx;
  color: #1D1D1D;
  box-sizing: border-box;
}

.dl-item {
  margin-top: 16rpx;
  display: inline-block;
  vertical-align: top;
  margin-right: 35rpx;
  width: 68rpx;
  height: 68rpx;
  line-height: 68rpx;
  text-align: center;
}

.dl-item:nth-child(7n) {
  margin-right: 0;
}

.dl-today {
  font-family: PingFangSC-Regular;
  font-size: 15px;
  color: #FFFFFF;
  border-radius: 50%;
  background: #21316A;
}

.dl-active {
  color: #1D1D1D;
}

.dl-disable {
  color: #808080;
}

.date-wrap-shadow {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, .5);
  z-index: 5;
}
/* end 日期选择 */

.js

Page({

  /**
   * 页面的初始数据
   */
  data: {
    yanse_column: 0,
    year_month: '',
    dayShow: false
  },

  /**
   * 获取今天的数据
   */
  todayDate () {
    let date = new Date()
    let year = date.getFullYear()
    let month = date.getMonth()
    let day = date.getDate()

    day = day < 10 ? '0' + day : day

    this.monthDaysUpdate(year, month)

    this.setData({
      _year: year,
      _month: month,
      year: year,
      month: month,
      day: day,
      year_month: year + '年' + (month + 1) + '月'
    })
  },

  /**
   * 年、月切换
   */
  yearMonthUpdate (flag) {
    let year = this.data.year
    let month = this.data.month
    let date = new Date(year, month + flag)
    
    year = date.getFullYear()
    month = date.getMonth()

    this.monthDaysUpdate(year, month)

    this.setData({
      year: year,
      month: month,
      year_month: year + '年' + (month + 1) + '月'
    })
  },

  /**
   * 月份天数
   * new Date: 把月份设置成下一个月,日期设置成 0,getDate()就获取这个月份的天数
   */
  monthDaysUpdate (year, month) {
    // 月份总天数
    let days = new Date(year, month + 1, 0).getDate()
    // 今天的日期
    let currYear = new Date().getFullYear()
    let currMonth = new Date().getMonth()
    let today = new Date().getDate()
    // 月份第一天是星期几
    let whichDay = new Date(year, month, 1).getDay()
    // 存放日期数组
    let dayList = []
    
    // 补空
    for (let j = 0; j < whichDay; j++) {
      let obj = { 'day': '' };
      dayList.push(obj)
    }

    for (let i = 1; i <= days; i++) {
      let obj = {
        'day': i,
      };

      if ((i < today && month <= currMonth && year <= currYear) || (month < currMonth && year <= currYear) || (year < currYear)) {
        obj['class'] = 'dl-active'  // 过去的天数
      }
      else if (i === today && month === currMonth && year === currYear) {
        obj['class'] = 'dl-today'
        obj['day'] = '今天'
      }
      else if (i > today && month >= currMonth && year >= currYear) {
        obj['class'] = 'dl-disable' // 未来的天数
      }
      else {
        obj['class'] = 'dl-disable' // 未来的天数
      }

      dayList.push(obj)
    }

    this.setData({
      dayList: dayList
    })
  },

  /**
   * 月份切换
   * index: -1 (前一个月) 1 (后一个月))
   */
  switchMonth (event) {
    let index = event.currentTarget.dataset.index

    if (parseInt(index) === -1) {
      this.yearMonthUpdate(-1)
    }
    else if (parseInt(index) === 1) {
      this.yearMonthUpdate(1)
    }
  },

  /**
   * 选择日期
   */
  selectDay (event) {
    let day = event.currentTarget.dataset.day
    let clazz = event.currentTarget.dataset.clazz
    let year = this.data.year
    let month = this.data.month

    if (clazz.indexOf('dl-disable') === -1) {
      if (day === '今天') {
        day = new Date().getDate()
      }

      day = day < 10 ? '0' + day : day

      this.setData({
        _year: year,
        _month: month,
        day: day,
        dayShow: false
      })
    }

    wx.pageScrollTo({
      scrollTop: 0,
      duration: 0
    })
  },

  /**
   * 日期面板展开
   */
  dayShow () {
    let dayShow = this.data.dayShow

    dayShow = dayShow ? false : true

    this.setData({
      dayShow: dayShow
    })
  },

  /**
   * 日期面板关闭
   */
  close_dayShow () {
    this.setData({
      dayShow: false
    })
  },

  /**
   * 
   */
})

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值