微信小程序实现打卡日历功能
程序员文章站
2022-07-02 21:47:33
生活中有各种可以打卡的app,例如背单词打卡什么的,本人觉得很有意思,于是本人在大二时做了一款诚信状打卡的微信小程序,这里讲述一下编写的过程。
先说一下开发环境:用的是微...
生活中有各种可以打卡的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": "打卡日历" }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: JS数组求和的常用方法实例小结