微信小程序?qū)崿F(xiàn)打卡日歷功能
生活中有各種可以打卡的app,例如背單詞打卡什么的,本人覺得很有意思,于是本人在大二時(shí)做了一款誠(chéng)信狀打卡的微信小程序,這里講述一下編寫的過程。
先說一下開發(fā)環(huán)境:用的是微信web開發(fā)工具開發(fā)的,后臺(tái)采用了Bmob后臺(tái),比較方便。
先展示一下成果:


話不多說,直接上代碼,里面也有挺多的注釋,以防自己忘記,當(dāng)然各位如果直接復(fù)制過去肯定不能有當(dāng)前的效果,注意后臺(tái)數(shù)據(jù)的交互,不過做一個(gè)界面還是沒有問題的。
Calendar.wxml 頁(yè)面文件
頁(yè)面上顯示出來(lái)的東西,布局上主要是一個(gè)年月欄、上一個(gè)月和下一個(gè)月的按鈕;然后是星期欄,就是日一二三四五六,然后就是每個(gè)月的日期,注意每個(gè)月的前面可能有空的地方。這里面用wx:if標(biāo)簽來(lái)區(qū)分當(dāng)前日期有無(wú)打卡的情況。
<!--pages/Calendar/Calendar.wxml-->
<!-- 打卡日歷頁(yè)面 -->
<view class='all'>
<view class="bar">
<!-- 上一個(gè)月 -->
<view class="previous" bindtap="handleCalendar" data-handle="prev">
<image src='../../images/pre.png'></image>
</view>
<!-- 顯示年月 -->
<view class="date">{{cur_year || "--"}} 年 {{cur_month || "--"}} 月</view>
<!-- 下一個(gè)月 -->
<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">
<!-- 每個(gè)月份的空的單元格 -->
<view class='cell' wx:if="{{days[j+k].date == null}}">
<text decode="{{true}}"> </text>
</view>
<!-- 每個(gè)月份的有數(shù)字的單元格 -->
<view class='cell' wx:else>
<!-- 當(dāng)前日期已簽到 -->
<view wx:if="{{days[j+k].isSign == true}}" style='background-color:#83C75D' class='cell'>
<text>{{days[j+k].date}}</text>
</view>
<!-- 當(dāng)前日期未簽到 -->
<view wx:else>
<text>{{days[j+k].date}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 堅(jiān)持打卡天數(shù) -->
<view class='count'>
<text>截至目前,你已堅(jiān)持打卡</text>
<view class='daynumber'>
<text class='number'>{{count}}</text>
<text class='day'>天</text>
</view>
<text>請(qǐng)?jiān)俳釉賲枺^續(xù)努力</text>
</view>
</view>
Calendar.wxss 樣式文件
這個(gè)就是讓頁(yè)面顯示得更好看一點(diǎn)了,里面有些屬性更改之后可能會(huì)導(dǎo)致整個(gè)頁(yè)面的格式變得很亂,說明自己的功夫還是不到家。
/* 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的操作了,感興趣的同學(xué)可以去參考它的官方文檔。
然后里面主要是對(duì)上一個(gè)月、下一個(gè)月的點(diǎn)擊函數(shù)進(jìn)行處理,以及對(duì)某年某月的每個(gè)日期進(jìn)行初始化(尤其是每個(gè)月前的可能有的幾個(gè)空格進(jìn)行了處理),然后就是判斷某個(gè)日期在后臺(tái)數(shù)據(jù)中是否有打卡。
// pages/Calendar/Calendar.js
//打卡日歷頁(yè)面
var util = require('../../utils/util.js');
var Bmob = require('../../utils/bmob.js');
Page({
/**
* 頁(yè)面的初始數(shù)據(jù)
*/
data: {
objectId:'',
days:[],
signUp:[],
cur_year:0,
cur_month:0,
count:0
},
/**
* 生命周期函數(shù)--監(jiān)聽頁(yè)面加載
*/
onLoad: function (options) {
this.setData({objectId : options.objectId});
//獲取當(dāng)前年月
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);
//獲取當(dāng)前用戶當(dāng)前任務(wù)的簽到狀態(tài)
this.onGetSignUp();
this.setData({
cur_year,
cur_month,
weeks_ch
})
},
/**
* 生命周期函數(shù)--監(jiān)聽頁(yè)面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁(yè)面顯示
*/
onShow: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁(yè)面隱藏
*/
onHide: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁(yè)面卸載
*/
onUnload: function () {
},
/**
* 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
*/
onPullDownRefresh: function () {
},
/**
* 頁(yè)面上拉觸底事件的處理函數(shù)
*/
onReachBottom: function () {
},
/**
* 用戶點(diǎn)擊右上角分享
*/
onShareAppMessage: function () {
},
// 獲取當(dāng)月共多少天
getThisMonthDays:function(year, month){
return new Date(year, month, 0).getDate()
},
// 獲取當(dāng)月第一天星期幾
getFirstDayOfWeek:function(year, month) {
return new Date(Date.UTC(year, month - 1, 1)).getDay();
},
// 計(jì)算當(dāng)月1號(hào)前空了幾個(gè)格子,把它填充在days數(shù)組的前面
calculateEmptyGrids:function(year, month) {
var that = this;
//計(jì)算每個(gè)月時(shí)要清零
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: []
});
}
},
// 繪制當(dāng)月天數(shù)占的格子,并把它放到days數(shù)組中
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
});
},
//匹配判斷當(dāng)月與當(dāng)月哪些日子簽到打卡
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});
},
// 切換控制年月,上一個(gè)月,下一個(gè)月
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
})
}
},
//獲取當(dāng)前用戶該任務(wù)的簽到數(shù)組
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文件
這里僅僅是改變了導(dǎo)航欄上的標(biāo)題文字
{
"navigationBarTitleText": "打卡日歷"
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript全局變量封裝模塊實(shí)現(xiàn)代碼
javascript全局變量封裝模塊的應(yīng)用,本文將詳細(xì)介紹,需要了解更多的朋友可以參考下2012-11-11
showModalDialog模態(tài)對(duì)話框的使用詳解以及瀏覽器兼容
showModalDialog是jswindow對(duì)象的一個(gè)方法,和window.open一樣都是打開一個(gè)新的頁(yè)面。區(qū)別是:showModalDialog打開子窗口后,父窗口就不能獲取焦點(diǎn)了(也就是無(wú)法操作了)2014-01-01
three.js 實(shí)現(xiàn)露珠滴落動(dòng)畫效果的示例代碼
這篇文章主要介紹了three.js 實(shí)現(xiàn)露珠滴落動(dòng)畫效果的示例代碼,非常不錯(cuò),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
CKEditor 4.4.1 添加代碼高亮顯示插件功能教程【使用官方推薦Code Snippet插件】
這篇文章主要介紹了CKEditor 4.4.1 添加代碼高亮顯示插件功能,涉及ckeditor使用官方推薦Code Snippet插件的相關(guān)操作布局與使用注意事項(xiàng),需要的朋友可以參考下2019-06-06
JavaScript實(shí)現(xiàn)文本中間縮略的兩種方案
項(xiàng)目中經(jīng)常會(huì)遇到縮略展示文字的場(chǎng)景,即要求文字在一行不換行展示,超出自動(dòng)展示...,常用的展示效果有兩種,文字中間縮略以及文字末尾縮略,本文將通過代碼示例給大家詳細(xì)的講一下這兩種方案,需要的朋友可以參考下2024-06-06

