美文网首页
小程序日历组件(选择区间日期)

小程序日历组件(选择区间日期)

作者: townYouth | 来源:发表于2021-01-25 09:57 被阅读0次

.wxml

<view class="calendar">

    <view class="calendar_header_box">

        <view class="cuIcon-back btn btnl {{prevBtn ? '' : 'cannot_edit'}}" bindtap="prevMonth"></view>

        <view class="time">{{year}}年{{month}}月</view>

        <view class="cuIcon-right btn btnr {{nextBtn ? '' : 'cannot_edit'}}" bindtap="nextMonth"></view>

    </view>

    <!--周标题-->

    <view class="calendar_weeks">

        <text wx:for="{{weekTitle}}" wx:key="index">{{item}}</text>

    </view>

    <!--日期-->

    <view class="calendar_days">

        <block wx:for="{{days_array}}" wx:for-item="item" wx:key="index" wx:for-index="i">

            <!--日期行-->

            <view class="calendar_row">

                <block wx:for="{{days_array[i]}}" wx:for-item="dayItem" wx:key="index">

                    <view class="calendar_cell {{dayItem.abled ? '' : 'cannot_edit'}} {{dayItem.isStart || dayItem.isEnd || dayItem.isToday ? 'flag_color' : ''}}" bindtap="dayClick" data-day="{{dayItem}}">

                        {{dayItem.day}}

                        <view class="flag_style {{dayItem.isToday ? 'today' : ''}} {{dayItem.isStart || dayItem.isEnd ? 'select_time' : ''}}" wx:if="{{dayItem.isStart || dayItem.isEnd || dayItem.isToday}}"></view>

                        <view class="during_style" wx:if="{{dayItem.during && dunringStyle}}"></view>

                        <view class="during_left" wx:if="{{dayItem.isStart && dunringStyle}}"></view>

                        <view class="during_right" wx:if="{{dayItem.isEnd && dunringStyle}}"></view>

                    </view>

                </block>

            </view>

        </block>

    </view>

</view>



.wxss

.calendar {

  width: 750rpx;

  height: 650rpx;

}

.calendar .calendar_header_box {

  width: 750rpx;

  height: 60rpx;

  display: flex;

  justify-content: center;

  align-items: center;

  font-size: 42rpx;

  color: #333333;

  text-align: center;

  margin-bottom: 30rpx;

}

.calendar .calendar_header_box .btn {

  width: 250rpx;

  height: 60rpx;

}

.calendar .calendar_header_box .btnl {

  text-align: right;

}

.calendar .calendar_header_box .btnr {

  text-align: left;

}

.calendar .calendar_header_box .time {

  width: 270rpx;

  position: relative;

  top: 5rpx;

  margin: 0 20rpx;

}

.calendar .calendar_weeks {

  width: 750rpx;

  height: 80rpx;

  padding: 0 60rpx;

  display: flex;

  justify-content: space-between;

  align-items: center;

  color: #999999;

  font-size: 37rpx;

}

.calendar .calendar_days {

  width: 750rpx;

  padding: 0 30rpx;

}

.calendar .calendar_days .calendar_row {

  width: 100%;

  height: 80rpx;

  display: flex;

  justify-content: space-between;

  align-items: center;

}

.calendar .calendar_days .calendar_row .calendar_cell {

  position: relative;

  height: 80rpx;

  flex: 1;

  text-align: center;

  line-height: 80rpx;

  font-size: 34rpx;

}

.calendar .calendar_days .calendar_row .calendar_cell .flag_style {

  width: 60rpx;

  height: 60rpx;

  border-radius: 50%;

  position: absolute;

  left: 50%;

  top: 50%;

  transform: translateX(-50%) translateY(-50%);

  z-index: -1;

}

.calendar .calendar_days .calendar_row .calendar_cell .during_style {

  width: 110rpx;

  height: 60rpx;

  border-radius: 10rpx;

  background-color: #D1F9D3;

  position: absolute;

  left: 50%;

  top: 50%;

  transform: translateX(-50%) translateY(-50%);

  z-index: -2;

}

.calendar .calendar_days .calendar_row .calendar_cell .during_left {

  width: 55rpx;

  height: 60rpx;

  background-color: #D1F9D3;

  position: absolute;

  left: 50%;

  top: 50%;

  transform: translateY(-50%);

  z-index: -2;

  border-radius: 10rpx;

}

.calendar .calendar_days .calendar_row .calendar_cell .during_right {

  width: 55rpx;

  height: 60rpx;

  background-color: #D1F9D3;

  position: absolute;

  right: 50%;

  top: 50%;

  transform: translateY(-50%);

  z-index: -2;

  border-radius: 10rpx;

}

.cannot_edit {

  color: #e7e7e7;

}

.today {

  background-color: var(--basecolor);

}

.select_time {

  background-color: #5BAC60;

}

.flag_color {

  color: #ffffff;

}



.js

Component({

  properties: {

    // 时间的性质 ‘start’ 选择开始时间 ‘end’ 选择结束时间

    type: {

      type: String,

      value: '',

      observer(newVal, oldVal, changedPath) {

        this.setData({

          typeOfTime: newVal,

          days_array: this.setCalendarData(this.data.year, this.data.month)

        })

      }

    },

    // 开始时间

    start: {

      type: String,

      value: '',

      observer(newVal, oldVal, changedPath) {

        this.setData({

          timeStart: new Date(newVal).getTime()

        })

      }

    },

    // 结束时间

    end: {

      type: String,

      value: '',

      observer(newVal, oldVal, changedPath) {

        this.setData({

          timeEnd: new Date(newVal).getTime()

        })

      }

    }

  },

  data: {

    year: new Date().getFullYear(), // 年份

    month: new Date().getMonth() + 1, // 月份

    day: new Date().getDate(), // 天

    days_array: [], // 日期数组

    weekTitle: ['日', '一', '二', '三', '四', '五', '六'], // 星期

    max_year: 2099, // 最大年份

    max_month: 12,  // 最大月份

    min_year: 1900, // 最小年份

    min_month: 1,  // 最小月份

    toyear: new Date().getFullYear(), // 今年

    tomonth: new Date().getMonth() + 1, // 今月

    today: new Date().getDate(), // 今天

    todayStamp: new Date().setHours(8, 0, 0, 0), // 今天的时间戳

    typeOfTime: '', // 时间的性质 ‘start’ 选择开始时间 ‘end’ 选择结束时间

    timeStart: null, // 开始服务时间戳

    timeEnd: null, // 结束服务时间戳

    dunringStyle: false, // 是否显示区间样式

    prevBtn: true, // 上个月是否可点

    nextBtn: true // 下个月是否可点

  },

  methods: {

    // 日历显示循环

    setCalendarData: function (year, month) {

      // 本月第一天是周几,0是星期日,6是星期六

      const empty_days_count = new Date(year, month - 1, 1).getDay()

      let empty_days = new Array

      const prev_month = month - 1 == 0 ? 12 : month - 1 // 上个月的月份数

      const prev_year = month - 1 == 0 ? this.data.year - 1 : this.data.year

      // 上个月的日期

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

        empty_days.push({

          day: -1,

          month: prev_month,

          year: prev_year,

          info: 'prev',

          date:`${prev_year}-${prev_month<10?`0${prev_month}`:prev_month}`

        })

      }

      // 下个月的日期

      const last_day = new Date(year, month, 0) // 本月最后一天

      const days_count = last_day.getDate() // 本月最后一天是几号

      const last_date = last_day.getDay() // 本月最后一天是星期几

      const next_month = month + 1 == 13 ? 1 : month + 1 // 下个月的月份数

      const next_year = month + 1 == 13 ? this.data.year + 1 : this.data.year

      let empty_days_last = new Array

      for (let i = 0; i < 6 - last_date; i++) {

        empty_days_last.push({

          day: -2,

          month: next_month,

          year: next_year,

          info: 'next',

          date:`${next_year}-${next_month<10?`0${next_month}`:next_month}`

        })

      }

      // 本月的日期

      let temp = new Array

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

        temp.push({

          day: i,

          month: month,

          year: year,

          info: 'current',

          date:`${year}-${month<10?`0${month}`:month}-${i<10?`0${i}`:i}`,

        })

      }

      let days = empty_days.concat(temp, empty_days_last) // 上个月 + 本月 + 下个月

      // 显示下月的日期

      let index = days.findIndex(element => { return element.day == -2 })

      if (index != -1) {

        const length = days.length

        const count = length - index

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

          days[index + i - 1].day = i

          days[index+i-1].date = `${days[index+i-1].date}-${i<10?`0${i}`:i}`

        }

      }

      // 显示上月的日期

      index = days.findIndex(element => { return element.day == 1 }) - 1

      if (index != -1) {

        // 获取上个月有多少天

        const last_month_day = new Date(year, month - 1, 0).getDate()

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

          days[i].day = last_month_day - index + i

          days[i].date = `${days[i].date}-${days[i].day<10?`0${days[i].day}`:days[i].day}`

        }

      }

      days.forEach(item => {

        item.stamp = new Date(item.date).getTime()

        // 判断是否是今天

        if (item.stamp == this.data.todayStamp) {

          item.isToday = true

        } else {

          item.isToday = false

        }

        // 判断是否可操作

        if (this.properties.type == 'start') {

          if (item.stamp < this.data.todayStamp || item.stamp > (this.data.timeEnd || 9999999999999)) {

            item.abled = false

          } else {

            item.abled = true

          }

        } else if (this.properties.type == 'end') {

          if (item.stamp < this.data.todayStamp || item.stamp < (this.data.timeStart || 0)) {

            item.abled = false

          } else {

            item.abled = true

          }

        } else {

          if (item.stamp < this.data.todayStamp) {

            item.abled = false

          } else {

            item.abled = true

          }

        }

        // 判断是否为开始日期或结束日期

        if (item.stamp == this.data.timeStart) {

          item.isStart = true

        } else {

          item.isStart = false

        }

        if (item.stamp == this.data.timeEnd) {

          item.isEnd = true

        } else {

          item.isEnd = false

        }

        // 判断是否为开始与结束之间的值

        if (this.data.timeEnd && this.data.timeStart) {

          if (item.stamp < this.data.timeEnd && item.stamp > this.data.timeStart) {

            item.during = true

          } else {

            item.during = false

          }

        } else {

          item.during = false

        }

      })

      // 判断是否显示区间样式

      if (this.data.timeStart && this.data.timeEnd && this.data.timeStart != this.data.timeEnd) {

        this.setData({

          dunringStyle: true

        })

      } else {

        this.setData({

          dunringStyle: false

        })

      }

      // 判断切换月份按钮是否可点

      let theNextYear

      let theNextMonth

      if (this.data.month == 12) {

        theNextYear = this.data.year + 1

        theNextMonth = 1

      } else {

        theNextYear = this.data.year

        theNextMonth = this.data.month + 1

      }

      const thisMonth = `${this.data.year}-${this.data.month<10?`0${this.data.month}`:this.data.month}-01`

      const nextMonth = `${theNextYear}-${theNextMonth<10?`0${theNextMonth}`:theNextMonth}-01`

      const thisMonthStamp = new Date(thisMonth).getTime()

      const nextMonthStamp = new Date(nextMonth).getTime()

      if (this.properties.type == 'start') {

        if (thisMonthStamp <= this.data.todayStamp) {

          this.setData({

            prevBtn: false

          })

        } else {

          this.setData({

            prevBtn: true

          })

        }

        if (nextMonthStamp > (this.data.timeEnd || 9999999999999)) {

          this.setData({

            nextBtn: false

          })

        } else {

          this.setData({

            nextBtn: true

          })

        }

      } else if (this.properties.type == 'end') {

        this.setData({

          nextBtn: true

        })

        if (thisMonthStamp <= this.data.todayStamp || thisMonthStamp < (this.data.timeStart || 0)) {

          this.setData({

            prevBtn: false

          })

        } else {

          this.setData({

            prevBtn: true

          })

        }

      }

      let days_array = new Array

      let week = new Array

      for (let i = 0; i < days.length; i++) {

        week.push(days[i])

        if (i % 7 == 6) {

          days_array.push(week)

          week = new Array

        }

      }

      if (week.length > 0) {

        days_array.push(week)

      }

      return days_array

    },

    // 点击下个月

    nextMonth: function () {

      if (!this.data.nextBtn) return

      const eventDetail = {

        prevYear: this.data.year,

        prevMonth: this.data.month

      }

      if (this.data.month == 12) {

        this.setData({

          year: this.data.year + 1,

          month: 1

        })

      } else {

        this.setData({

          month: this.data.month + 1

        })

      }

      this.setData({

        days_array: this.setCalendarData(this.data.year, this.data.month)

      })

      eventDetail['currentYear'] = this.data.year

      eventDetail['currentMonth'] = this.data.month

      this.triggerEvent('nextMonth', eventDetail)

    },

    //点击上个月

    prevMonth: function () {

      if (!this.data.prevBtn) return

      if (this.data.month == 1) {

        this.setData({

          year: this.data.year - 1,

          month: 12

        })

      } else {

        this.setData({

          month: this.data.month - 1

        })

      }

      this.setData({

        days_array: this.setCalendarData(this.data.year, this.data.month)

      })

    },

    //日期选择器变化

    dateChange: function (event) {

      const value = event.detail.value

      const date = new Date(value)

      const year = date.getFullYear()

      const month = date.getMonth() + 1

      this.setData({

        year: year,

        month: month,

        days_array: this.setCalendarData(year, month)

      })

    },

    //点击具体日期

    dayClick: function (event) {

      const click_day = event.currentTarget.dataset.day

      if (!click_day.abled) return

      this.triggerEvent('daysclick', click_day)

      this.setData({

        days_array: this.setCalendarData(this.data.year, this.data.month)

      })

    }

  },

  lifetimes: {

    created: function () {

    },

    attached: function () {

      this.setData({

        days_array: this.setCalendarData(this.data.year, this.data.month)

      })

    },

    ready: function () {

    },

  }

})



.json

{

  "component": true,

  "usingComponents": {}

}

相关文章

网友评论

      本文标题:小程序日历组件(选择区间日期)

      本文链接:https://www.haomeiwen.com/subject/gzjbzktx.html