前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小程序日历选择源码

小程序日历选择源码

原创
作者头像
谭广健
修改2021-09-07 18:15:16
2.7K0
修改2021-09-07 18:15:16
举报
文章被收录于专栏:谭广健的专栏谭广健的专栏

因为在开发一个微信小程序与海康威视人脸机设备的通讯系统,所以隔了多个月没写什么原创文章了,目前项目硬件通讯功能和用户控制基本打通;今天就直接带来干货,发一个小程序日历选择并计算当前日期之差的天数代码。想继续看记得关注哦~

我们先来说一下小程序的日期选择,小程序的日期选择很多人都说有原生的,但原生的日期选择不能直观地显示日期所属的星期;例如周六日原生的就无法显示,当然可以选择后再判断,但这个感觉不是太人性。那就自己动手写一个日期选择日历。怎么写呢。。。

弹出的日历选择器
弹出的日历选择器

首先小程序开发工具的目录下面找一个“components”,建立一个目录“calendar”;这样我们就将日期日历写为组件方便调用。

当然文件也就那四个js、json、wxml、wxss。其中重点在js和wxml里面,wxss样式代码也分享吧,代码如下:

代码语言:javascript
复制
//calendar.js
Component({
  properties: {
    start: {
      type: String,
      value: '',
      observer: function (newVal) {
        if (typeof (newVal) == 'string' && newVal.length > 0) {
          var t = new Date(newVal)
          if (!isNaN(t.getTime())) {
            var y = t.getFullYear(),
              m = t.getMonth(),
              d = t.getDate()
            this.setData({
              startDate: [y, m, d]
            })
          }
        }
      }
    },
    end: {
      type: String,
      value: '',
      observer: function (newVal) {
        if (typeof (newVal) == 'string' && newVal.length > 0) {
          var t = new Date(newVal)
          if (!isNaN(t.getTime())) {
            var y = t.getFullYear(),
              m = t.getMonth(),
              d = t.getDate()
            this.setData({
              endDate: [y, m, d]
            })
          }
        }
      }
    },
    value: {
      type: String,
      value: '',
      observer: function (newVal) {
        if (typeof (newVal) == 'string' && newVal.length > 0) {
          var t = new Date(newVal)
          if (!isNaN(t.getTime())) {
            var y = t.getFullYear(),
              m = t.getMonth(),
              d = t.getDate()
            this.setData({
              valueDate: [y, m, d],
              year: y,
              month: m
            })
          }
        }
      }
    },
  },
  data: {
    show: true,
    startDate: [],
    endDate: [],
    valueDate: [],
    year: new Date().getFullYear(),
    month: new Date().getMonth(),
    days: []
  },
  methods: {
    loadData: function () {
      var that = this,
        data = that.data,
        year = data.year,
        month = data.month,
        valueDate = data.valueDate,
        startDate = data.startDate,
        endDate = data.endDate,
        date = new Date(year, month, 1),
        week = date.getDay(),
        days = [],
        last = new Date(year, (month + 1), 0),
        max = last.getDate(),
        lastWeek = last.getDay()
      if (week > 0) {
        for (var i = 0; i < week; i++) {
          days.push({
            day: 0
          })
        }
      }
      if (valueDate[0]) var currentTime = new Date(valueDate[0], valueDate[1], valueDate[2]).getTime()
      if (startDate[0]) var startTime = new Date(startDate[0], startDate[1], startDate[2]).getTime()
      if (endDate[0]) var endTime = new Date(endDate[0], endDate[1], endDate[2]).getTime()
      for (var i = 1; i <= max; i++) {
        var current = false,
          disabled = false,
          d = new Date(year, month, i),
          t = d.getTime()
        if (currentTime && currentTime == t) current = true
        if (startTime && startTime > t) disabled = true
        if (endTime && endTime < t) disabled = true
        days.push({
          day: i,
          current: current,
          disabled: disabled
        })
      }
      if (lastWeek != 6) {
        for (var i = 0, l = (6 - lastWeek); i < l; i++) {
          days.push({
            day: 0
          })
        }
      }
      that.setData({
        days: days
      })
    },
    prevMonth: function () {
      var that = this,
        data = that.data,
        year = data.year,
        month = data.month,
        date = new Date(year, (month - 1), 1)
      that.setData({
        year: date.getFullYear(),
        month: date.getMonth()
      }, () => {
        that.loadData()
      })
    },
    nextMonth: function () {
      var that = this,
        data = that.data,
        year = data.year,
        month = data.month,
        date = new Date(year, (month + 1), 1)
      that.setData({
        year: date.getFullYear(),
        month: date.getMonth()
      }, () => {
        that.loadData()
      })
    },
    changeMonth: function (e) {
      var that = this,
        value = e.detail.value,
        date = new Date(value + '-01')
      that.setData({
        year: date.getFullYear(),
        month: date.getMonth()
      }, () => {
        that.loadData()
      })
    },
    changeDate: function (e) {
      var that = this,
        data = that.data,
        year = data.year,
        month = data.month,
        days = data.days,
        index = e.currentTarget.dataset.i,
        value = {}
      if (days[index] && days[index].day > 0 && !days[index].disabled) {
        if (!days[index].current) {
          for (var i = 0, l = days.length; i < l; i++) {
            if (days[i].current) {
              days[i].current = false
              break
            }
          }
        }
        days[index].current = true
        that.setData({
          days: days
        })
        that.closeCalendar()
        value.year = year
        month += 1
        value.month = month
        value.day = days[index].day
        value.date = year + '-' + (month < 10 ? '0' + month : month) + '-' + (days[index].day < 10 ? '0' + days[index].day : days[index].day)
        that.triggerEvent('doChange', value)
      }
    },
    closeCalendar: function () {
      var that = this
      that.setData({
        show: false
      })
      setTimeout(function () {
        that.triggerEvent('doClose')
      }, 400)
    }
  },
  attached: function () {
    this.loadData()
  }
})
代码语言:javascript
复制
<!--calendar.wxml-->
<view bindtap="closeCalendar" class="mask {{show?'mask_show':'mask_hide'}}"></view>
<view class="popup {{show?'popup_show':'popup_hide'}}">
	<view class="popup_head">
		<view bindtap="closeCalendar" class="popup_cancel">取消</view>
		<view class="popup_month">
			<view bindtap="prevMonth" class="popup_prev"></view>
			<picker mode="date" bindchange="changeMonth" fields="month" value="{{year}}-{{(month+1)}}" start="{{startDate[0]?startDate[0]+'-'+(startDate[1]+1)+'-1':''}}" end="{{endDate[0]?endDate[0]+'-'+(endDate[1]+1)+'-1':''}}">
				<view class="popup_month_picker">{{year}}年{{(month+1)}}月</view>
			</picker>
			<view bindtap="nextMonth" class="popup_next"></view>
		</view>
	</view>
	<view class="popup_body">
		<view class="cal">
			<view class="cal_week">
				<view class="cal_week_text">日</view>
				<view class="cal_week_text">一</view>
				<view class="cal_week_text">二</view>
				<view class="cal_week_text">三</view>
				<view class="cal_week_text">四</view>
				<view class="cal_week_text">五</view>
				<view class="cal_week_text">六</view>
			</view>
			<view class="cal_days">
				<view wx:for="{{days}}" wx:key="index" bindtap="changeDate" data-i="{{index}}" class="cal_day {{item.current?'current':''}} {{item.disabled?'disabled':''}}">{{item.day>0?item.day:''}}</view>
			</view>
		</view>
	</view>
</view>
代码语言:javascript
复制
/*calendar.wxss*/
.mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 9000;
}

.mask_show {
  animation: mask_show ease 0.3s forwards;
}

@keyframes mask_show {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.mask_hide {
  animation: mask_hide ease 0.3s forwards;
}

@keyframes mask_hide {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
  }
}

.popup {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: #fff;
  z-index: 9001;
  padding-bottom: env(safe-area-inset-bottom);
}

.popup_show {
  animation: popup_show ease 0.3s forwards;
}

@keyframes popup_show {
  0% {
    transform: translate(0, 100%);
    opacity: 0;
  }

  100% {
    transform: translate(0, 0);
    opacity: 1;
  }
}

.popup_hide {
  animation: popup_hide ease 0.3s forwards;
}

@keyframes popup_hide {
  0% {
    transform: translate(0, 0);
    opacity: 1;
  }

  100% {
    transform: translate(0, 100%);
    opacity: 0;
  }
}

.popup_head {
  border-top: 2rpx solid #f6f6f6;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx 30rpx;
  font-size: 34rpx;
}

.popup_cancel {
  color: #888;
}

.popup_month {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.popup_prev,
.popup_next {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 30rpx;
}

.popup_prev::before,
.popup_next::before {
  display: block;
  content: '';
  box-sizing: border-box;
  box-sizing: border-box;
  width: 12rpx;
  height: 24rpx;
  border-top: 12rpx solid #fff;
  border-bottom: 12rpx solid #fff;
}

.popup_prev {
  margin-right: 20rpx;
}

.popup_prev::before {
  border-right: 12rpx solid #888;
}

.popup_next {
  margin-left: 20rpx;
}

.popup_next::before {
  border-left: 12rpx solid #888;
}

.popup_month_picker {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.popup_month_picker::after {
  margin-left: 8rpx;
  display: block;
  content: '';
  box-sizing: border-box;
  width: 24rpx;
  height: 12rpx;
  border-top: 12rpx solid #888;
  border-left: 12rpx solid #fff;
  border-right: 12rpx solid #fff;
}

.popup_body {
  border-top: 2rpx solid #f6f6f6;
  padding-top: 16rpx;
  padding-bottom: 16rpx;
}

.cal {
  width: 728rpx;
  margin: 0 auto;
}

.cal_week {
  display: flex;
  justify-content: flex-start;
  align-items: center;
}

.cal_week_text {
  width: 104rpx;
  padding: 8rpx 0;
  text-align: center;
  color: #999;
  font-size: 24rpx;
}

.cal_days {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: wrap;
  font-size: 30rpx;
}

.cal_day {
  width: 104rpx;
  border-top: 2rpx solid #eee;
  padding: 16rpx 0;
  text-align: center;
}

.cal_days .current {
  background: #1890ff;
  color: #fff;
}

.cal_days .disabled {
  color: #ccc;
}

最后就是怎么调用,其实很简单,直接在相关的小程序里面

代码语言:javascript
复制
<view bindtap="showCalendar">选择日期:{{date}}</view>
<calendar wx:if="{{showCalendar}}" start="2021-09-05" end="2021-09-07" value="{{date}}" bind:doChange="_doChange" bind:doClose="_doClose"></calendar>

里面的参数我就不说了,也就起止及返回值,那么js呢,好吧,也一块给出

代码语言:javascript
复制
Page({
  data: {
    date: '',
    showCalendar: false
  },
  showCalendar: function () {
    this.setData({
      showCalendar: true
    })
  },
  //选择日期
  _doChange: function (e) {
  //计算相差的日期
    var start_time=new Date(this.data.tomorrow.replace(/-/g, "/"));
    var end_time = new Date(e.detail.date.replace(/-/g, "/"));
    var days = end_time.getTime() - start_time.getTime();
    var day = parseInt(days / (1000 * 60 * 60 * 24));
    console.log(day);
  //计算相差的日期    
    this.setData({
      date: e.detail.date
    })
  },
  //关闭选择器
  _doClose: function () {
    this.setData({
      showCalendar: false
    })
  }
})

最后到这里还有关键的一步就是调用我们的这个组件,那怎么调用呢,在JSON里面加入

代码语言:javascript
复制
{
  "usingComponents": {
    "calendar": "/components/calendar/calendar"
  }
}

好,大功告成。。多谢各位看官~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档