微信小程序实现打卡日历功能

生活中有各种可以打卡的app,例如背单词打卡什么的,本人觉得很有意思,于是本人在大二时做了一款诚信状打卡的微信小程序,这里讲述一下编写的过程。

先说一下开发环境:用的是微信web开发工具开发的,后台采用了Bmob后台,比较方便。

先展示一下成果:

话不多说,直接上代码,里面也有挺多的注释,以防自己忘记,当然各位如果直接复制过去肯定不能有当前的效果,注意后台数据的交互,不过做一个界面还是没有问题的。

Calendar.wxml 页面文件

页面上显示出来的东西,布局上主要是一个年月栏、上一个月和下一个月的按钮;然后是星期栏,就是日一二三四五六,然后就是每个月的日期,注意每个月的前面可能有空的地方。这里面用wx:if标签来区分当前日期有无打卡的情况。

<!--pages/Calendar/Calendar.wxml-->
<!-- 打卡日历页面 -->
<view class='all'>
 <view class="bar">
  <!-- 上一个月 -->
  <view class="previous" bindtap="handleCalendar" data-handle="prev">
   <image src='../../images/pre.png'></image>
  </view>
  <!-- 显示年月 -->
  <view class="date">{{cur_year || "--"}} 年 {{cur_month || "--"}} 月</view>
  <!-- 下一个月 -->
  <view class="next" bindtap="handleCalendar" data-handle="next">
   <image src='../../images/next.png'></image>
  </view>
 </view>
 <!-- 显示星期 -->
 <view class="week">
  <view wx:for="{{weeks_ch}}" wx:key="{{index}}" data-idx="{{index}}">{{item}}</view>
 </view>
 <view class='days'>
  <!-- 列 -->
  <view class="columns" wx:for="{{days.length/7}}" wx:for-index="i" wx:key="i">
   <view wx:for="{{days}}" wx:for-index="j" wx:key="j">
    <!-- 行 -->
    <view class="rows" wx:if="{{j/7 == i}}">
     <view class="rows" wx:for="{{7}}" wx:for-index="k" wx:key="k">
      <!-- 每个月份的空的单元格 -->
      <view class='cell' wx:if="{{days[j+k].date == null}}">
       <text decode="{{true}}">  </text>
      </view>
      <!-- 每个月份的有数字的单元格 -->
      <view class='cell' wx:else>
       <!-- 当前日期已签到 -->
       <view wx:if="{{days[j+k].isSign == true}}" style='background-color:#83C75D' class='cell'>
        <text>{{days[j+k].date}}</text>
       </view>
       <!-- 当前日期未签到 -->
       <view wx:else>
        <text>{{days[j+k].date}}</text>
       </view>
      </view>
     </view>
    </view>
   </view>
  </view>
 </view>
 <!-- 坚持打卡天数 -->
 <view class='count'>
  <text>截至目前,你已坚持打卡</text>
  <view class='daynumber'>
  <text class='number'>{{count}}</text>
  <text class='day'>天</text>
  </view>
  <text>请再接再厉,继续努力</text>
 </view>
</view>

Calendar.wxss 样式文件

这个就是让页面显示得更好看一点了,里面有些属性更改之后可能会导致整个页面的格式变得很乱,说明自己的功夫还是不到家。

/* pages/Calendar/Calendar.wxss */
/* 打卡日历 */
.all{
 margin-top: 20rpx;
}

.all .bar{
 display: flex;
 flex-direction: row;
 justify-content: space-between;
 margin: 30rpx 20rpx;
 padding: 10rpx;
}

.all .bar image{
 width: 50rpx;
 height: 50rpx;
}

.all .week{
 display: flex;
 flex-direction: row;
 justify-content: space-between;
 padding: 20rpx;
 padding-left: 40rpx;
 padding-right: 40rpx;
 margin: 20rpx;
 border-radius: 10px;
 background-color: #acd;
}

.all .days{
 margin: 20rpx;
 padding: 10rpx;
 border-radius: 10px;
 background-color: #acd;

}

.all .columns{
 display: flex;
 flex-direction: column;
 justify-content: space-between;
}

.all .columns .rows{
 display: flex;
 flex-direction: row;
 justify-content: space-between;
}

.all .columns .rows .cell{
 width: 84rpx;
 height: 88rpx;
 margin: 3rpx;
 text-align: center;
 border-radius: 50%;
 display: flex;
 flex-direction: column;
 justify-content: center;
}

.count .daynumber{
 display: flex;
 flex-direction: row;
 justify-content: center;
}

.count .daynumber .day{
 margin-top: 50rpx;
}

.count{
 margin: 20rpx;
 padding: 30rpx;
 display: flex;
 text-align: center;
 border-radius: 10px;
 flex-direction: column;
 justify-content: center;
 background-color: #acd;
 align-items: center;
}

.count .number{
 color: red;
 font-size: 60rpx;
 background-color: #fff;
 width: 100rpx;
 height: 100rpx;
 border-radius: 50%;
 display: flex;
 flex-direction: column;
 justify-content: center;
 margin: 20rpx;
}

.count text{
 margin: 10rpx;
}

Calendar.js JavaScript文件

js文件里面涉及到Bmob的操作,这里就不多说Bmob的操作了,感兴趣的同学可以去参考它的官方文档。
然后里面主要是对上一个月、下一个月的点击函数进行处理,以及对某年某月的每个日期进行初始化(尤其是每个月前的可能有的几个空格进行了处理),然后就是判断某个日期在后台数据中是否有打卡。

// pages/Calendar/Calendar.js
//打卡日历页面
var util = require('../../utils/util.js');
var Bmob = require('../../utils/bmob.js');
Page({

 /**
  * 页面的初始数据
  */
 data: {
  objectId:'',
  days:[],
  signUp:[],
  cur_year:0,
  cur_month:0,
  count:0
 },

 /**
  * 生命周期函数--监听页面加载
  */
 onLoad: function (options) {
  this.setData({objectId : options.objectId});
  //获取当前年月
  const date = new Date();
  const cur_year = date.getFullYear();
  const cur_month = date.getMonth() + 1;
  const weeks_ch = ['日', '一', '二', '三', '四', '五', '六'];
  this.calculateEmptyGrids(cur_year, cur_month);
  this.calculateDays(cur_year, cur_month);
  //获取当前用户当前任务的签到状态
  this.onGetSignUp();
  this.setData({
   cur_year,
   cur_month,
   weeks_ch
  })

 },

 /**
  * 生命周期函数--监听页面初次渲染完成
  */
 onReady: function () {

 },

 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function () {

 },

 /**
  * 生命周期函数--监听页面隐藏
  */
 onHide: function () {

 },

 /**
  * 生命周期函数--监听页面卸载
  */
 onUnload: function () {

 },

 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function () {

 },

 /**
  * 页面上拉触底事件的处理函数
  */
 onReachBottom: function () {

 },

 /**
  * 用户点击右上角分享
  */
 onShareAppMessage: function () {

 },
 // 获取当月共多少天
 getThisMonthDays:function(year, month){
   return new Date(year, month, 0).getDate()
 },

 // 获取当月第一天星期几
 getFirstDayOfWeek:function(year, month) {
  return new Date(Date.UTC(year, month - 1, 1)).getDay();
 },

 // 计算当月1号前空了几个格子,把它填充在days数组的前面
 calculateEmptyGrids:function(year, month) {
  var that = this;
  //计算每个月时要清零
  that.setData({days:[]});
  const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
  if (firstDayOfWeek > 0) {
   for (let i = 0; i < firstDayOfWeek; i++) {
    var obj = {
     date:null,
     isSign:false
    }
    that.data.days.push(obj);
   }
   this.setData({
    days:that.data.days
   });
  //清空
  } else {
   this.setData({
    days: []
   });
  }
 },

 // 绘制当月天数占的格子,并把它放到days数组中
 calculateDays:function(year, month) {
  var that = this;
  const thisMonthDays = this.getThisMonthDays(year, month);
  for (let i = 1; i <= thisMonthDays; i++) {
   var obj = {
    date: i,
    isSign: false
   }
   that.data.days.push(obj);
  }
  this.setData({
   days:that.data.days
  });
 },

 //匹配判断当月与当月哪些日子签到打卡
 onJudgeSign:function(){
  var that = this;
  var signs = that.data.signUp;
  var daysArr = that.data.days;
  for (var i=0; i < signs.length;i++){
   var current = new Date(signs[i].date.replace(/-/g, "/"));
   var year = current.getFullYear();
   var month = current.getMonth()+1;
   var day = current.getDate();
   day = parseInt(day);
   for (var j = 0; j < daysArr.length;j++){
    //年月日相同并且已打卡
    if (year == that.data.cur_year && month == that.data.cur_month && daysArr[j].date == day && signs[i].isSign == "今日已打卡"){
     daysArr[j].isSign = true;
    }
   }
  }
  that.setData({days:daysArr});
 },

 // 切换控制年月,上一个月,下一个月
 handleCalendar:function(e) {
  const handle = e.currentTarget.dataset.handle;
  const cur_year = this.data.cur_year;
  const cur_month = this.data.cur_month;
  if (handle === 'prev') {
   let newMonth = cur_month - 1;
   let newYear = cur_year;
   if (newMonth < 1) {
    newYear = cur_year - 1;
    newMonth = 12;
   }
   this.calculateEmptyGrids(newYear, newMonth);
   this.calculateDays(newYear, newMonth);
   this.onGetSignUp();
   this.setData({
    cur_year: newYear,
    cur_month: newMonth
   })
  } else {
   let newMonth = cur_month + 1;
   let newYear = cur_year;
   if (newMonth > 12) {
    newYear = cur_year + 1;
    newMonth = 1;
   }
   this.calculateEmptyGrids(newYear, newMonth);
   this.calculateDays(newYear, newMonth);
   this.onGetSignUp();
   this.setData({
    cur_year: newYear,
    cur_month: newMonth
   })
  }
 },

 //获取当前用户该任务的签到数组
 onGetSignUp:function(){
  var that = this;
  var Task_User = Bmob.Object.extend("task_user");
  var q = new Bmob.Query(Task_User);
  q.get(that.data.objectId, {
   success: function (result) {
    that.setData({
     signUp : result.get("signUp"),
     count : result.get("score")
    });
    //获取后就判断签到情况
    that.onJudgeSign();
   },
   error: function (object, error) {
   }
  });
 }
})

Calendar.json json文件

这里仅仅是改变了导航栏上的标题文字

{
 "navigationBarTitleText": "打卡日历"
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信小程序日历/日期选择插件使用方法详解

    微信小程序日历选择器插件点击日历日期可以获取到年月日,具体内容如下 wxml <view class="canlendarBgView"> <view class="canlendarView"> <view class="canlendarTopView"> <view class="leftBgView" bindtap="handleCalendar" dat

  • 微信小程序日历组件使用方法详解

    这个日历采用小程序组件化开发,有兴趣的同学可以引用本组件(怎么引用不多赘述,自行去微信小程序开发api了解) wxml <!--pages/components/calender.wxml--> <view class='calender'> <view class='operate'> <text catchtap='reduce'>减少</text> <text catchtap="add">增加</te

  • 微信小程序日历组件calendar详解及实例

    微信小程序日历组件calendar详解及实例 模版使用: src="../cal/calendar.wxml"> is="calendar" data="{{selected_value,days,month,years,lunar_years,lunar_month,lunar_days,selectDateType,l unar_selected_value}}"> JS代码使用: var Calendar = require('

  • 微信小程序实现日历功能

    本文实例为大家分享了微信小程序实现日历功能的具体代码,供大家参考,具体内容如下 效果图: 代码: <view class="calendar"> <view class="selectDate"> <view class="goleft iconfont icon-jianzuo" bindtap="prevMonth"></view> <view class="

  • 微信小程序日历效果

    本文实例为大家分享了微信小程序日历效果的具体代码,供大家参考,具体内容如下 源码下载地址 项目需要一个日历功能,花了一天时间实现的微信小程序日历,js大小只有几k,引入了bootstrap字体图标(文件icon.wxss,该字体已经bootstrap字体图标需要的字体)看起来有80k,出去icon.wxss整个只有几k,有问题欢迎指正 如图: index.wxml <view class="page"> <view class="box">

  • 微信小程序自定义可滑动日历界面

    本文实例为大家分享了微信小程序可滑动日历界面的具体代码,供大家参考,具体内容如下 参考某个博主的自定义控件做了一些改动,希望这篇博客能帮助需要的人. WXML <view class='container'> <view class='month flex m-around'> <view class='arrow' bindtap='prevMonth'>< </view> <view class='year-and-month'> &l

  • 微信小程序自定义带价格显示日历效果

    本文实例为大家分享了微信小程序自定义日历效果的具体代码,供大家参考,具体内容如下 JS代码: var Moment = require("../../utils/moment.js"); var DATE_YEAR = new Date().getFullYear(); var DATE_MONTH = new Date().getMonth() + 1; var DATE_DAY = new Date().getDate(); Page({ data: { year: '', mon

  • 微信小程序日历弹窗选择器代码实例

    应公司需求,写了一个弹窗日历选择器,感觉用着还不错,封装了一下,分享给大家,希望大家有什么意见可以指出来相互交流共同改进! 先上一个效果图:(当天日期为2018-4-18) 时间改为5月份的效果图: 直接上代码: wxml: <view class="weui-cells weui-cells_after-title" style='margin-top:100rpx;'> <view class="weui-cell weui-cell_access&qu

  • 微信小程序可滑动周日历组件使用详解

    微信小程序可滑动周日历组件,供大家参考,具体内容如下 看网上周日历组件比较少,自己弄了一个,和大家分享一下. 如果样式变形,请检查是否有共用样式起冲突 展示一下效果图 在components组件文件夹下新建calendarWeek文件夹 直接上代码吧: index.wxml <!--components/calendarWeek/index.wxml--> <!-- 日历 --> <view class="date-choose shrink border-bott

  • 微信小程序可滑动月日历组件使用详解

    微信小程序可滑动月日历组件 此日历可进行左右滑动,展示签到打卡信息,和大家分享一下. 如果样式变形,请检查是否有共用样式起冲突 展示一下效果图 在components组件文件夹下新建calendarMonth文件夹 直接上代码吧: index.wxml <!--components/calendar/index.wxml--> <view class='month'> <!-- <view class='arrow' bindtap='prevMonth'><

  • 微信小程序实现日历效果

    本文实例为大家分享了微信小程序实现日历效果的具体代码,供大家参考,具体内容如下 效果预览: wxml部分: <view class='box1' style='width: {{ sysW * 7 }}px'> <view class='dateBox'>{{ year }} - {{ month}}</view> <block wx:for='{{ weekArr }}'> <view style='width: {{ sysW }}px; heig

随机推荐