小程序-自定义日历控件

微信小程序开发过程,需求用到日历控件,方便选日期安排事情,我们只能通过自定义实现日历组件。毕竟不像js,jquery那么多的先例直接引用方便,我们只有通过组件形式来实现。

效果如图:

image.png


代码结构:

image.png


组件页面文件:calendar.wxml

<view class="calendar">

  <view class='tit'>

    <view class='pre' bindtap='gotoPreMonth'>{{'<'}}</view>

    <view class='current'>{{currentYear}}年{{currentMonth}}月</view>

    <view class='next' bindtap='gotoNextMonth'>{{'>'}}</view>

  </view>

  <view class='content'>

    <view></view>

    <view></view>

    <view></view>

    <view></view>

    <view></view>

    <view></view>

    <view></view>

    <view

      wx:for="{{allArr}}"

      wx:key="{{index}}"

      class="{{item.month == 'current' ? '' : 'gray'}}"

    ><text catchtap='dateclick' data-date="{{currentMonth+'月'+item.date}}">{{item.date}}</text></view>

  </view>

</view>


组件样式文件:calendar.wxss

.calendar{

  width: 100%;

}

.calendar .tit{

  display: flex;

  justify-content: center;

  align-items: center;

  font-size: 36rpx;

  color: #2A2A2A;

  padding: 40rpx 0;

}

.calendar .tit .current{

  margin: 0 40rpx;

}

.calendar .content{

  display: flex;

  flex-wrap: wrap;

  box-sizing: border-box;

  padding-left: 25rpx;

}

.calendar .content view{

  width: 100rpx;

  height: 80rpx;

  line-height: 80rpx;

  text-align: center;

  flex-shrink: 0;

  font-size: 34rpx;

  color: #2A2A2A;

  /* background: rgb(224, 199, 199); */

  margin: 14rpx 0;

}

.calendar .content .gray{

  color: #999;

}


组件JS文件:calendar.js

// components/calendar/calendar.js

Component({

/**

    * 组件的属性列表

    */

  properties: {

    currentYear: { // 当前显示的年

      type: Number,

      value: new Date().getFullYear()

    },

    currentMonth: { // // 当前显示的月

      type: Number,

      value: new Date().getMonth() + 1

    }

  },


/**

    * 组件的初始数据

    */

  data: {

    currentMonthDateLen: 0, // 当月天数

    preMonthDateLen: 0, // 当月中,上月多余天数

    allArr:[], // 当月所有数据

  },

  ready(){

    this.getAllArr()

  },


/**

    * 组件的方法列表

    */

  methods: {

    // 获取某年某月总共多少天

    getDateLen(year, month) {

      let actualMonth = month - 1;

      let timeDistance = +new Date(year, month) - +new Date(year, actualMonth);

      return timeDistance / (1000 * 60 * 60 * 24);

    },

    // 获取某月1号是周几

    getFirstDateWeek(year, month) {

      return new Date(year, month - 1, 1).getDay()

    },

    // 上月 年、月

    preMonth(year, month) {

      if (month == 1) {

        return {

          year: --year,

          month: 12

        }

      } else {

        return {

          year: year,

          month: --month

        }

      }

    },

    // 下月 年、月

    nextMonth(year, month) {

      if (month == 12) {

        return {

          year: ++year,

          month: 1

        }

      } else {

        return {

          year: year,

          month: ++month

        }

      }

    },

    // 获取当月数据,返回数组

    getCurrentArr(){

      let currentMonthDateLen = this.getDateLen(this.data.currentYear, this.data.currentMonth) // 获取当月天数

      let currentMonthDateArr = [] // 定义空数组

      if (currentMonthDateLen > 0) {

        for (let i = 1; i <= currentMonthDateLen; i++) {

          currentMonthDateArr.push({

            month: 'current', // 只是为了增加标识,区分上下月

            date: i

          })

        }

      }

      this.setData({

        currentMonthDateLen

      })

      return currentMonthDateArr

    },

    // 获取当月中,上月多余数据,返回数组

    getPreArr(){

      let preMonthDateLen = this.getFirstDateWeek(this.data.currentYear, this.data.currentMonth) // 当月1号是周几 == 上月残余天数)

let preMonthDateArr = [] // 定义空数组

      if (preMonthDateLen > 0) {

        let { year, month } = this.preMonth(this.data.currentYear, this.data.currentMonth) // 获取上月 年、月

        let date = this.getDateLen(year, month) // 获取上月天数

        for (let i = 0; i < preMonthDateLen; i++) {

          preMonthDateArr.unshift({ // 尾部追加

month: 'pre', // 只是为了增加标识,区分当、下月

            date: date

          })

          date--

        }

      }

      this.setData({

        preMonthDateLen

      })

      return preMonthDateArr

    },

    // 获取当月中,下月多余数据,返回数组

    getNextArr() {

      let nextMonthDateLen = 42 - this.data.preMonthDateLen - this.data.currentMonthDateLen // 下月多余天数

      let nextMonthDateArr = [] // 定义空数组

      if (nextMonthDateLen > 0) {

        for (let i = 1; i <= nextMonthDateLen; i++) {

          nextMonthDateArr.push({

month: 'next',// 只是为了增加标识,区分当、上月

            date: i

          })

        }

      }

      return nextMonthDateArr

    },

    // 整合当月所有数据

    getAllArr(){

      let preArr = this.getPreArr()

      let currentArr = this.getCurrentArr()

      let nextArr = this.getNextArr()

      let allArr = [...preArr, ...currentArr, ...nextArr]

      this.setData({

        allArr

      })

      let sendObj = {

        currentYear: this.data.currentYear,

        currentMonth: this.data.currentMonth,

        allArr: allArr

      }

      // console.log(sendObj)

      this.triggerEvent('sendObj', sendObj)

    },

    // 点击 上月

    gotoPreMonth(){

      let { year, month } = this.preMonth(this.data.currentYear, this.data.currentMonth)

      this.setData({

        currentYear: year,

        currentMonth: month

      })

      this.getAllArr()

    },

    // 点击 下月

    gotoNextMonth() {

      let { year, month } = this.nextMonth(this.data.currentYear, this.data.currentMonth)

      this.setData({

        currentYear: year,

        currentMonth: month

      })

      this.getAllArr()

    },

dateclick:function(e){

console.log(e.currentTarget.dataset.date);

}

  }

})


以上已经完成了组件的主体内容,接下来是页面引用

一个使用组件的页面,引用很简单:

<calendar

  currentYear='{{currentyear}}'

  currentMonth="{{currentmonth}}"

  bindsendObj='getCalendarData' 

></calendar>


对应的js文件也是一些初始化参数的传递:

data: {

currentyear: '',

currentmonth: '',

currentday: ''

},


/**

  * 生命周期函数--监听页面加载

  */

onLoad: function(options) {

var da = new Date();

var year = da.getFullYear();

var month = da.getMonth() + 1;

var day = da.getDay();

this.setData({

currentyear: year,

currentmonth: month,

currentday: day

})

},


这样进到页面引用组件,会有默认当前日期。通过以上这些文件就实现了一套日历页面,其它就不写了,没什么内容。


另外提供一个demo下载地址


链接:https://pan.baidu.com/s/17sEPdni99fRcsNA7DHtGMA 

提取码:m7my 


转载请注明来源:梦幻岛 dreamisland.wang


关于我 |  合作伙伴 |  用户注册 |  帮助中心 |  版权声明