微信小程序 日历控件

源码地址: https://github.com/huangxiongbiao12/BGCalendar

一、效果图

B71B80B9-0D2B-41A7-988E-E66A221DCDA6.png

二、用法

1、进入界面的时候传入startDate、endDate格式为yyyy-MM-dd字符串

var startDate = this.data.startDate;
    var endDate = this.data.endDate;
    console.log(startDate);
    console.log(endDate);
     wx.navigateTo({
        url: '../calender/index?startDate='+startDate+"&endDate="+endDate,
        success: function(res){
          // success
        },
      })

2、返回处理
接收startDate、endDate格式为yyyy-MM-dd字符串处理界面

三、代码

1、js代码

var Data = require("../../utils/data.js");

Page({
  data: {
  },
  //==================加载数据================
  onLoad: function(options) {
    console.log(options.startDate);
    console.log(options.endDate);
    if(options.startDate&&options.endDate) {
       console.log(options.startDate);
      console.log(options.endDate);
        // var startDate = Data.formatDate(options.startDate,"yyyy-MM-dd");
        // var endDate =  Data.formatDate(options.endDate,"yyyy-MM-dd");
        this.data.startDate = options.startDate;
        this.data.endDate = options.endDate;
    }
    var date = new Date();
    //获取当前的年月
    var cur_year = date.getFullYear();
    var cur_month = date.getMonth() + 1;
    var cur_day = date.getDate();
    console.log(cur_year);
    console.log(cur_month);
    console.log(cur_day);
    const weeks_ch = ['日', '一', '二', '三', '四', '五', '六'];
    //设置数据
    this.setData({
      org_year:date.getFullYear(),//现在时间的年月日
      org_month:date.getMonth(),
      org_day:cur_day,
      weeks_ch
    })
    this.initData(cur_year,cur_month);
  },
  //初始化数据
  initData:function(cur_year,cur_month) {
      // 计算最近三个月的对象
    var mObject0 = this.calculateDays(cur_year, cur_month);
    if(cur_month+1>12) {
      cur_year = cur_year+1;
      cur_month = 1;
    }else {
      cur_month = cur_month+1;
    }
    var mObject1 = this.calculateDays(cur_year, cur_month);
    if(cur_month+1>12) {//月不能大于12
      cur_year = cur_year+1;
      cur_month = 1;
    }else {
      cur_month = cur_month+1;
    }
    var mObject2 = this.calculateDays(cur_year, cur_month);
    this.setData({
      allDays:[mObject0,mObject1,mObject2]
    });
  },
  // =============获取当月有多少天(下个月月初是多少)==========
  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();
  },
  //====================计算当前年月空的几天 =============
  calculateEmptyGrids: function(year, month) {
    const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
    let empytGrids = [];
    if (firstDayOfWeek > 0) {
      for (let i = 0; i < firstDayOfWeek; i++) {
        empytGrids.push(i);
      }
    }
    return empytGrids;
  },
   // =====================计算当前年月有哪些天===========
   /**
    * 根据年月计算当前月的天对象状态返回对象
    * mObject 年月对象
    * year  年
    * month 月
    * hasEmptyGrid  是都有空调
    * empytGrids  空天数字
    * days 所有日对象【】
    */
  calculateDays: function(year, month) {
    var mObject = {};//月对象
    mObject["year"] = year;
    mObject["month"] = month;
    //计算当前年月空的几天
    var empytGrids = this.calculateEmptyGrids(year, month);
    if(empytGrids.length>0) {
      mObject["hasEmptyGrid"] = true;
      mObject["empytGrids"] = empytGrids;
    }else {
      mObject["hasEmptyGrid"] = false;
      mObject["empytGrids"] = [];
    }
    var days = [];
    var thisMonthDays = this.getThisMonthDays(year, month);//这个月有多少天
    //现在的时间
     var cusDate = new Date(this.data.org_year, this.data.org_month,this.data.org_day);
     var startDate;
     var endDate;
     if(this.data.startDate&&this.data.endDate) {
        startDate = Data.stringToDate(this.data.startDate);
        endDate = Data.stringToDate(this.data.endDate);
     }
     if(this.data.startDate){
       startDate = Data.stringToDate(this.data.startDate);
     }
    for (let i = 1; i <= thisMonthDays; i++) {
      var day = {};
      //加入的时间
      var date = new Date(year, month-1,i);
      // console.log(date)
      //status 0-不可选择 1-当前时间 2-可选择 3-被选中
      day["day"] = i;
      //比现在的时间比较是大于还是小于,小于则不可点击
      var time = parseInt(Data.calculateTime(date,cusDate)); 
      if(time<0) {
          day["status"] = 0;
      }else if(time==0) {
          day["status"] = 1;
      }else {
          day["status"] = 2;
      }
      if(this.data.startDate&&this.data.endDate) {
        var stime = parseInt(Data.calculateTime(date,startDate)); 
        var etime = parseInt(Data.calculateTime(date,endDate));
        if(stime>=0&&etime<=0) {
            day["status"] = 3;
        }
      }else if(this.data.startDate){
         var stime = parseInt(Data.calculateTime(date,startDate)); 
        if(stime==0) {
            day["status"] = 3;
        }
      }
      days.push(day);
    }
    mObject["days"] = days;
    return mObject;
  },
// 选择时间
  selectAction: function(e) {
      console.log(e.currentTarget.dataset.object);
      var year = e.currentTarget.dataset.object.year;
      var month = e.currentTarget.dataset.object.month;
      var day = e.currentTarget.dataset.idx+1;
      console.log(year);
      console.log(month);
      console.log(day);
      var selectDate = new Date(year,month-1,day);
      //现在的时间
     var cusDate = new Date(this.data.org_year, this.data.org_month,this.data.org_day);
      var time = parseInt(Data.calculateTime(selectDate,cusDate));
      console.log(time);
      if(time<0) {
        console.log("请选择合理的时间");
         wx.showToast({
                  title: '请选择合理的时间',
                  icon: 'error',
                  duration: 2000
          })
          return;
      }
      if(this.data.startDate&&this.data.endDate) {
          this.data.startDate = Data.formatDate(selectDate,"yyyy-MM-dd");
          this.data.endDate = null;
      }else if(this.data.startDate) {
          this.data.endDate = Data.formatDate(selectDate,"yyyy-MM-dd");
      }else {
           this.data.startDate = Data.formatDate(selectDate,"yyyy-MM-dd");
      } 
      this.initData(this.data.org_year, this.data.org_month+1);
      //返回选择的时间(有起止时间的时候返回)
       if(this.data.startDate&&this.data.endDate) {
         console.log(this.data.startDate);
         console.log(this.data.endDate);
         var sDate = this.data.startDate;
         var eDate = this.data.endDate;
          var pages = getCurrentPages();
          var prevPage = pages[pages.length - 2]; //上一个页面
          //直接调用上一个页面的setData()方法,把数据存到上一个页面中去
          prevPage.setData({
            startDate:sDate,
            endDate:eDate
          })
          wx.navigateBack({
            delta: 1, // 回退前 delta(默认为1) 页面
            success: function(res){
              // success
            },
            fail: function(res) {
              // fail
            },
            complete: function(res) {
              // complete
            }
          })
       }
  }

});

utils/data.js部分代码
/** 
//提供接口
module.exports = {
    formatDate:formatDate,//格式化日期
    stringToDate:stringToDate,//字符串转日期
    calculateTime:calculateTime//比较时间差
}
   * 字符串转时间(yyyy-MM-dd HH:mm:ss) 
   * result (分钟) 
   */ 
  function stringToDate(fDate){  
    var fullDate = fDate.split("-");  
    return new Date(fullDate[0], fullDate[1]-1, fullDate[2], 0, 0, 0);  
  } 
  
  
/** 
     * 格式化日期 
     * @param date 日期 
     * @param format 格式化样式,例如yyyy-MM-dd HH:mm:ss E 
     * @return 格式化后的金额 
     */
    function formatDate(date, format) { 
      var v = ""; 
      if (typeof date == "string" || typeof date != "object") { 
        return; 
      } 
      var year  = date.getFullYear(); 
      var month  = date.getMonth()+1; 
      var day   = date.getDate(); 
      var hour  = date.getHours(); 
      var minute = date.getMinutes(); 
      var second = date.getSeconds(); 
      var weekDay = date.getDay(); 
      var ms   = date.getMilliseconds(); 
      var weekDayString = ""; 
        
      if (weekDay == 1) { 
        weekDayString = "星期一"; 
      } else if (weekDay == 2) { 
        weekDayString = "星期二"; 
      } else if (weekDay == 3) { 
        weekDayString = "星期三"; 
      } else if (weekDay == 4) { 
        weekDayString = "星期四"; 
      } else if (weekDay == 5) { 
        weekDayString = "星期五"; 
      } else if (weekDay == 6) { 
        weekDayString = "星期六"; 
      } else if (weekDay == 7) { 
        weekDayString = "星期日"; 
      } 
  
      v = format; 
      //Year 
      v = v.replace(/yyyy/g, year); 
      v = v.replace(/YYYY/g, year); 
      v = v.replace(/yy/g, (year+"").substring(2,4)); 
      v = v.replace(/YY/g, (year+"").substring(2,4)); 
  
      //Month 
      var monthStr = ("0"+month); 
      v = v.replace(/MM/g, monthStr.substring(monthStr.length-2)); 
  
      //Day 
      var dayStr = ("0"+day); 
      v = v.replace(/dd/g, dayStr.substring(dayStr.length-2)); 
  
      //hour 
      var hourStr = ("0"+hour); 
      v = v.replace(/HH/g, hourStr.substring(hourStr.length-2)); 
      v = v.replace(/hh/g, hourStr.substring(hourStr.length-2)); 
  
      //minute 
      var minuteStr = ("0"+minute); 
      v = v.replace(/mm/g, minuteStr.substring(minuteStr.length-2)); 
  
      //Millisecond 
      v = v.replace(/sss/g, ms); 
      v = v.replace(/SSS/g, ms); 
        
      //second 
      var secondStr = ("0"+second); 
      v = v.replace(/ss/g, secondStr.substring(secondStr.length-2)); 
      v = v.replace(/SS/g, secondStr.substring(secondStr.length-2)); 
        
      //weekDay 
      v = v.replace(/E/g, weekDayString); 
      return v; 
    }
    /**
     * 计算两个日期相差几天
     * cusDate 当前时间
     * oriDate  比较时间
     * 返回 正数为cusDate>oriDate
     */
    function calculateTime(cusDate,oriDate) {
      var cusTime = cusDate.getTime();
      var oriTime = oriDate.getTime();
      return (cusTime-oriTime)/(1000*60*60*24)
    }

2、wxml代码


<view class="weeks box">
    <view class="week fs28" wx:for="{{weeks_ch}}" wx:key="{{index}}" data-idx="{{index}}">{{item}}
    </view>
</view>

<block wx:for="{{allDays}}" wx:for-item="object">
    <!--年月-->
    <view class="date-area" style="">
        <view>{{object.year || "--"}} 年 {{object.month || "--"}} 月</view>
    </view>
    <!--日-->
    <view class="days">
        <!--循环空-->
        <view wx:if="{{object.hasEmptyGrid}}" class="grid white-color" wx:for="{{object.empytGrids}}" wx:key="{{index}}" data-idx="{{index}}"></view>
        <!--循环天-->
        <view class="grid white-color" wx:for="{{object.days}}" wx:key="{{index}}" data-idx="{{index}}"  data-object="{{object}}" bindtap="selectAction" style="">
            <!--天-->
            <view class="day {{item.status==0 ? 'disable' : 'enable'}} {{item.status==3 ? 'border-radius pink-bg' : ''}}">{{item.day}}</view>
            <!--今天-->
            <view wx:if="{{item.status==1}}" style="color:gray;font-size:12px;text-align:center;">今天</view>
        </view>
    </view>
</block>
  

3、icxx代码

.box {
    display: flex;
    align-content: center;
    align-items: center;
}

.pink-color {
  color: rgb(64, 70, 128);
}
.white-color {
  color: #fff;
}
.fs24 {
  font-size: 24rpx;
}
.fs28 {
  font-size: 28rpx;
}
.fs32 {
  font-size: 32rpx;
}
.fs36 {
  font-size: 36rpx;
}
/* pages/calendar/calendar.wxss ====================================*/

.date-area {
    width: 100%;
    padding: 10px 0;
    text-align: center;
    border-top: 1px solid lightgray; 
    border-bottom: 1px solid lightgray;
}
.weeks {
    padding: 10px 0;
    height: 50rpx;
    line-height: 50rpx;
}
.week {
    flex: 1;
    text-align: center;
}
.days {
    display: flex;
    flex-wrap: wrap;
    align-content: center;
    align-items: center;
}
.grid {
    display: flex;
    width: 107.1428571429rpx;
    flex-direction: column;
    align-items: center;
    align-content: center;
    margin: 5px 0;
    text-align: center;
    /*border: 1px solid lightgray;*/
}
.day {
    width: 65rpx;
    padding: 13rpx 0; 
    color: black;
    font-size: 26rpx;
    font-weight: 200;
    text-align: center;
}
.border-radius {
    border-radius: 50%;
    position: relative;
    left: 0;
    top: 0;
    color: #fff;
}
.disable {
    color: lightgray;
}
.pink-bg {
    background-color: rgb(64, 70, 128);
}
.purple-bg {
    background-color: #b8b8f1;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容