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


Posted in Javascript onOctober 21, 2019

微信小程序可滑动月日历组件

此日历可进行左右滑动,展示签到打卡信息,和大家分享一下。
如果样式变形,请检查是否有共用样式起冲突

展示一下效果图

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

在components组件文件夹下新建calendarMonth文件夹

直接上代码吧:

index.wxml

<!--components/calendar/index.wxml-->
<view class='month'>
  <!-- <view class='arrow' bindtap='prevMonth'>《 </view> -->
  <view>
    <picker mode="date" value="{{date}}" start="2015-09" end="2020-09" fields='month' bindchange="bindDateChange">
    <view >
      {{date}}
    </view>
    </picker>
  </view>
  <!-- <view class='arrow' bindtap='nextMonth'> 》</view> -->
</view>
<view class='container'>
<view class='calendar flex column s-center'>
 <view class='week-row flex m-around wid100'>
  <view class='grid' wx:for="{{week}}" wx:key='item'>{{item}}</view>
 </view>
 <swiper class='swpier-box' circular="true" current="{{swiperIndex}}" bindchange='swiperChange'>
  <swiper-item class='flex m-around days-table '>
   <view wx:for="{{calendar.first}}" wx:for-item='x' wx:key='x.date'
    class='grid fw {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' bindtap='bindDayTap'>
     <view class='view {{x.year+"-"+x.month+"-"+x.day === date+"-01"?"choice2":""}}'>{{x.date === today?'今天':x.day}}</view>
      <block wx:if="{{workerClockData.length>0}}">
       <view wx:for="{{workerClockData}}" wx:key="{{index}}">
       <text class='da' wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">记</text>
       <text class='da2'wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">+{{item.actualDayWage}}</text>
       </view>
      </block>
   </view>
  </swiper-item>
  <swiper-item class='flex m-around days-table '>
   <view wx:for="{{calendar.second}}" wx:for-item='x' wx:key='x.date'
    class='grid fw {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' data-test='{{(year + "-" +month + "-" + day)}}' bindtap='bindDayTap'>
    <view class='view {{x.year+"-"+x.month+"-"+x.day === date+"-01"?"choice2":""}}'>{{x.date === today?'今天':x.day}}</view>
    <block wx:if="{{workerClockData.length>0}}">
     <view wx:for="{{workerClockData}}" wx:key="{{index}}">
      <text class='da' wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">记</text>
      <text class='da2'wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">+{{item.actualDayWage}}</text>
     </view>
    </block>
   </view>
  </swiper-item>
  <swiper-item class='flex m-around days-table'>
   <view wx:for="{{calendar.third}}" wx:for-item='x' wx:key='x.date'
    class='grid fw {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' bindtap='bindDayTap'>
     <view class='view {{x.year+"-"+x.month+"-"+x.day === date+"-01"?"choice2":""}}{{x.month === month?"":"notCurrent"}}'>{{x.date === today?'今天':x.day}}</view>
     <block wx:if="{{workerClockData.length>0}}">
     <view wx:for="{{workerClockData}}" wx:key="{{index}}">
      <text class='da' wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">记</text>
      <text class='da2'wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">+{{item.actualDayWage}}</text>
     </view>
    </block>
   </view>
  </swiper-item>
  <swiper-item class='flex m-around days-table '>
   <view wx:for="{{calendar.fourth}}" wx:for-item='x' wx:key='x.date'
    class='grid fw {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' bindtap='bindDayTap'>
     <view class='view {{x.year+"-"+x.month+"-"+x.day === date+"-01"?"choice2":""}}'>{{x.date === today?'今天':x.day}}</view>
     <block wx:if="{{workerClockData.length>0}}">
      <view wx:for="{{workerClockData}}" wx:key="{{index}}">
      <text class='da' wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">记</text>
      <text class='da2'wx:if="{{x.year+'-'+x.month+'-'+x.day==item.clockDate}}">+{{item.actualDayWage}}</text>
     </view>
    </block>
   </view>
  </swiper-item>
 </swiper>
</view>
</view>

index.wxss

/* pages/calendar/calendar.wxss */
.container{
 width: 100%;
 height: auto;
 padding: 6rpx;
 font-size: 28rpx;
}
 .month{
 width: 100%;
 height: 100rpx;
 display: flex;
 align-items: center;
 justify-content: center;
 font-size: 32rpx;
  color:#333333;
  font-weight: 700;
 border-bottom: 1px solid #f5f5f5;
}
.days-table {
 flex-wrap: wrap;
 align-content: flex-start;
}
.wid100{
 width: 100%;
}
.calendar{
 z-index:10000;
 
}

.grid {
 /* width: 107.14rpx; */
 height: 100rpx;
 text-align: center;
 line-height: 100rpx;
 font-size:.7rem;
 color:#333333;
 flex: 1;
}
.today {
 color: red;
}
.grid view {
 height:85rpx;
 line-height: 85rpx;
 width:85rpx;
 flex: 1
}
.choice2 {
 /* border-radius: 50%; */
 background: silver;
 background-position:center;
 color: white;
}
.choice .view{
 flex: 1;
 border-radius: 50%;
 background: #88a1fd;
 background-position:center;
 color: white;
 display: flex;
 align-items: center;
 justify-content: center
}
.fw {
 font-weight: 700;
 font-size: 28rpx;
 position: relative;
}
.grid text.da{
 display: flex;
 width: 32rpx;
 height: 32rpx;
 position: absolute;
 right:12rpx;
 top:1rpx;
 font-weight: 1000;
 background: red;
 border-radius: 50%;
 overflow: hidden;
 text-align: center;
 line-height: 24rpx;
 color: #ffffff;
 font-size: 8px;
align-items: center;
justify-content: center
}
.grid text.da2 {
 width: 100%;
 height: 100%;
 text-align: center;
 font-size: 12px;
 font-weight: 800;
 color: red;
 position: absolute;
 bottom:-25rpx;
 display: flex;
 left: -4rpx;
 align-items: center;
 justify-content: center;
 
}
/* 非本月日期 */
.notCurrent {
 color: silver;
 font-weight: normal
}
.day-hover {
 background: red;
}
.container .corred {
 color: red;
}
.swpier-box {
 height: 600rpx;
 width: 100%;
}
.arrow {
 width: 100rpx;
 color: #88a1fd;
 text-align: center;
}

.flex {
 display: flex;
}
/* 轴向 */
.column {
 flex-direction: column;
}
/* 主轴方向 */
.m-start {
 justify-content: flex-start;
}

.m-end {
 justify-content: flex-end;
}

.m-around {
 justify-content: space-around;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

.m-between {
 justify-content: space-between;
}
.m-center {
 justify-content: center;
}
/* 侧轴方向 */
.s-start {
 align-items: flex-start;
}
.s-end {
 align-items: flex-end;
}

.s-around {
 align-items: space-around;
}
.s-between {
 align-items: space-between;
}
.s-center {
 align-items: center;
}

index.js

// components/calendar/index.js
let choose_year = null,
 choose_month = null;
Component({
 /**
  * 组件的属性列表
  */
 properties: {
  workerClockData: {
   type: Array,
   observer: function (newVal, oldVal, changedPath) {
    // console.log(newVal, oldVal, changedPath,this)
   }

  }
 },

 /**
  * 组件的初始数据
  */
 data: {
  day: '',
  year: '',
  month: '',
  date: '2017-01',
  today: '',
  week: ['日', '一', '二', '三', '四', '五', '六'],
  calendar: {
   first: [],
   second: [],
   third: [],
   fourth: []
  },
  swiperMap: ['first', 'second', 'third', 'fourth'],
  swiperIndex: 1,
  showCaldenlar: false
 },
 ready: function () {
  this.getinit()

 },

 /**
  * 组件的方法列表
  */
 methods: {
  getinit() { //初始化
   const date = new Date()
    , month = this.formatMonth(date.getMonth() + 1)
    , year = date.getFullYear()
    , day = this.formatDay(date.getDate())
    , today = `${year}-${month}-${day}`
   let calendar = this.generateThreeMonths(year, month)
   // console.log(calendar)
   this.setData({
    calendar,
    month,
    year,
    day,
    today,
    beSelectDate: today,
    date: `${year}-${month}`
   })
  },
  showCaldenlar() {
   this.setData({
    showCaldenlar: !this.data.showCaldenlar
   })
  },
  /**
   * 
   * 左右滑动
   * @param {any} e 
   */
  swiperChange(e) {
   const lastIndex = this.data.swiperIndex
    , currentIndex = e.detail.current

   let flag = false
    , { year, month, day, today, date, calendar, swiperMap } = this.data
    , change = swiperMap[(lastIndex + 2) % 4]
    , time = this.countMonth(year, month)
    , key = 'lastMonth'
   console.log(lastIndex, currentIndex)
   if (lastIndex > currentIndex) {
    lastIndex === 3 && currentIndex === 0
     ? flag = true
     : null

   } else {
    lastIndex === 0 && currentIndex === 3
     ? null
     : flag = true
   }
   if (flag) {
    key = 'nextMonth'
   }
   console.log(key)
   year = time[key].year
   month = time[key].month
   date = `${year}-${month}`
   day = ''

   if (today.indexOf(date) !== -1) {
    day = today.slice(-2)
   }

   time = this.countMonth(year, month)
   calendar[change] = null
   calendar[change] = this.generateAllDays(time[key].year, time[key].month)

   this.setData({
    swiperIndex: currentIndex,
    //文档上不推荐这么做,但是滑动并不会改变current的值,所以随之而来的计算会出错
    year,
    month,
    date,
    day,
    calendar
   })
   // console.log(calendar)
  },
  /**
   * 
   * 点击切换月份,生成本月视图以及临近两个月的视图
   * @param {any} year 
   * @param {any} month 
   * @returns {object} calendar
   */
  generateThreeMonths(year, month) {
   let { swiperIndex, swiperMap, calendar } = this.data
    , thisKey = swiperMap[swiperIndex]
    , lastKey = swiperMap[swiperIndex - 1 === -1 ? 3 : swiperIndex - 1]
    , nextKey = swiperMap[swiperIndex + 1 === 4 ? 0 : swiperIndex + 1]
    , time = this.countMonth(year, month)
   delete calendar[lastKey]
   calendar[lastKey] = this.generateAllDays(time.lastMonth.year, time.lastMonth.month)
   delete calendar[thisKey]
   calendar[thisKey] = this.generateAllDays(time.thisMonth.year, time.thisMonth.month)
   delete calendar[nextKey]
   calendar[nextKey] = this.generateAllDays(time.nextMonth.year, time.nextMonth.month)
   return calendar
  },
  bindDayTap(e) {
   let { month, year } = this.data
    , time = this.countMonth(year, month)
    , tapMon = e.currentTarget.dataset.month
    , day = e.currentTarget.dataset.day
   if (tapMon == time.lastMonth.month) {
    this.changeDate(time.lastMonth.year, time.lastMonth.month)
   } else if (tapMon == time.nextMonth.month) {
    this.changeDate(time.nextMonth.year, time.nextMonth.month)
   } else {
    this.setData({
     day
    })
   }
   let beSelectDate = e.currentTarget.dataset.date;
   this.setData({
    beSelectDate,
    showCaldenlar: false
   })
   // console.log(beSelectDate)
  },
  bindDateChange(e) {
   if (e.detail.value === this.data.date) {
    return
   }

   const month = e.detail.value.slice(-2)
    , year = e.detail.value.slice(0, 4)

   this.changeDate(year, month)
  },
  prevMonth(e) {
   let { year, month } = this.data
    , time = this.countMonth(year, month)
   this.changeDate(time.lastMonth.year, time.lastMonth.month)
  },
  nextMonth(e) {
   let { year, month } = this.data
    , time = this.countMonth(year, month)
   this.changeDate(time.nextMonth.year, time.nextMonth.month)
  },
  /**
   * 
   * 直接改变日期
   * @param {any} year 
   * @param {any} month 
   */
  changeDate(year, month) {
   let { day, today } = this.data
    , calendar = this.generateThreeMonths(year, month)
    , date = `${year}-${month}`
   date.indexOf(today) === -1
    ? day = '01'
    : day = today.slice(-2)

   this.setData({
    calendar,
    day,
    date,
    month,
    year,
   })
  },
  /**
   * 
   * 月份处理
   * @param {any} year 
   * @param {any} month 
   * @returns 
   */
  countMonth(year, month) {
   let lastMonth = {
    month: this.formatMonth(parseInt(month) - 1)
   }
    , thisMonth = {
     year,
     month,
     num: this.getNumOfDays(year, month)
    }
    , nextMonth = {
     month: this.formatMonth(parseInt(month) + 1)
    }

   lastMonth.year = parseInt(month) === 1 && parseInt(lastMonth.month) === 12
    ? `${parseInt(year) - 1}`
    : year + ''
   lastMonth.num = this.getNumOfDays(lastMonth.year, lastMonth.month)
   nextMonth.year = parseInt(month) === 12 && parseInt(nextMonth.month) === 1
    ? `${parseInt(year) + 1}`
    : year + ''
   nextMonth.num = this.getNumOfDays(nextMonth.year, nextMonth.month)
   return {
    lastMonth,
    thisMonth,
    nextMonth
   }
  },
  currentMonthDays(year, month) {
   const numOfDays = this.getNumOfDays(year, month)
   return this.generateDays(year, month, numOfDays)
  },
  /**
   * 生成上个月应显示的天
   * @param {any} year 
   * @param {any} month 
   * @returns 
   */
  lastMonthDays(year, month) {
   const lastMonth = this.formatMonth(parseInt(month) - 1)
    , lastMonthYear = parseInt(month) === 1 && parseInt(lastMonth) === 12
     ? `${parseInt(year) - 1}`
     : year
    , lastNum = this.getNumOfDays(lastMonthYear, lastMonth) //上月天数
   let startWeek = this.getWeekOfDate(year, month - 1, 1) //本月1号是周几
    , days = []
   if (startWeek == 7) {
    return days
   }

   const startDay = lastNum - startWeek

   return this.generateDays(lastMonthYear, lastMonth, lastNum, { startNum: startDay, notCurrent: true })
  },
  /**
   * 生成下个月应显示天
   * @param {any} year 
   * @param {any} month
   * @returns 
   */
  nextMonthDays(year, month) {
   const nextMonth = this.formatMonth(parseInt(month) + 1)
    , nextMonthYear = parseInt(month) === 12 && parseInt(nextMonth) === 1
     ? `${parseInt(year) + 1}`
     : year
    , nextNum = this.getNumOfDays(nextMonthYear, nextMonth) //下月天数
   let endWeek = this.getWeekOfDate(year, month)    //本月最后一天是周几
    , days = []
    , daysNum = 0
   if (endWeek == 6) {
    return days
   } else if (endWeek == 7) {
    daysNum = 6
   } else {
    daysNum = 6 - endWeek
   }
   return this.generateDays(nextMonthYear, nextMonth, daysNum, { startNum: 1, notCurrent: true })
  },
  /**
   * 
   * 生成一个月的日历
   * @param {any} year 
   * @param {any} month 
   * @returns Array
   */
  generateAllDays(year, month) {
   let lastMonth = this.lastMonthDays(year, month)
    , thisMonth = this.currentMonthDays(year, month)
    , nextMonth = this.nextMonthDays(year, month)
    , days = [].concat(lastMonth, thisMonth, nextMonth)
   // console.log("jin")
   // console.log(year, month, days)
   return days
  },
  /**
   * 
   * 生成日详情
   * @param {any} year 
   * @param {any} month 
   * @param {any} daysNum 
   * @param {boolean} [option={
   *  startNum:1,
   *  grey: false
   * }] 
   * @returns Array 日期对象数组
   */
  generateDays(year, month, daysNum, option = {
   startNum: 1,
   notCurrent: false
  }) {
   const weekMap = ['一', '二', '三', '四', '五', '六', '日']
   let days = []
   for (let i = option.startNum; i <= daysNum; i++) {
    let week = weekMap[new Date(year, month - 1, i).getUTCDay()]
    let day = this.formatDay(i)
    days.push({
     date: `${year}-${month}-${day}`,
     event: false,
     day,
     week,
     month,
     year
    })
   }
   return days
  },
  /**
   * 
   * 获取指定月第n天是周几 |
   * 9月第1天: 2017, 08, 1 |
   * 9月第31天:2017, 09, 0 
   * @param {any} year 
   * @param {any} month 
   * @param {number} [day=0] 0为最后一天,1为第一天
   * @returns number 周 1-7, 
   */
  getWeekOfDate(year, month, day = 0) {
   let dateOfMonth = new Date(year, month, 0).getUTCDay() + 1;
   dateOfMonth == 7 ? dateOfMonth = 0 : '';
   return dateOfMonth;
  },
  /**
   * 
   * 获取本月天数
   * @param {number} year 
   * @param {number} month 
   * @param {number} [day=0] 0为本月0最后一天的
   * @returns number 1-31
   */
  getNumOfDays(year, month, day = 0) {
   return new Date(year, month, day).getDate()
  },
  /**
   * 
   * 月份处理
   * @param {number} month 
   * @returns format month MM 1-12
   */
  formatMonth(month) {
   let monthStr = ''
   if (month > 12 || month < 1) {
    monthStr = Math.abs(month - 12) + ''
   } else {
    monthStr = month + ''
   }
   monthStr = `${monthStr.length > 1 ? '' : '0'}${monthStr}`
   return monthStr
  },
  formatDay(day) {
   return `${(day + '').length > 1 ? '' : '0'}${day}`
  }

 }
})

调用组件

//json文件调用
"usingComponents": {
   "calendarMonth": "../../components/calendarMonth/index"
}

页面调用组件

//workerClockData 传过去的数据 显示签到金额 和 记
<calendarMonth workerClockData="{{workerClockData}}"></calendarMonth>

要显示打卡数据要传入参数,格式为如下,格式为数组

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

更多精彩的日历效果请学习参考专题:javascript日历插件

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

Javascript 相关文章推荐
jQuery 文本框得失焦点的简单实例
Feb 19 Javascript
通过js为元素添加多项样式,浏览器全兼容写法
Aug 30 Javascript
jquery中使用循环下拉菜单示例代码
Sep 24 Javascript
jQuery中:nth-child选择器用法实例
Dec 31 Javascript
jquery实现表单获取短信验证码代码
Mar 13 Javascript
JavaScript定义函数的三种实现方法
Sep 23 Javascript
浅谈Vue.nextTick 的实现方法
Oct 25 Javascript
使用webpack打包koa2 框架app
Feb 02 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
Jan 08 Javascript
JS拖拽排序插件Sortable.js用法实例分析
Feb 20 Javascript
微信小程序和H5页面间相互跳转代码实例
Sep 19 Javascript
微信小程序实现弹幕墙(祝福墙)
Nov 18 Javascript
微信小程序可滑动周日历组件使用详解
Oct 21 #Javascript
小程序实现横向滑动日历效果
Oct 21 #Javascript
微信小程序实现点击图片放大预览
Oct 21 #Javascript
vue实现Input输入框模糊查询方法
Jan 29 #Javascript
mpvue实现左侧导航与右侧内容的联动
Oct 21 #Javascript
vue项目中常见问题及解决方案(推荐)
Oct 21 #Javascript
vue.js实现左边导航切换右边内容
Oct 21 #Javascript
You might like
PHP面向对象法则
2012/02/23 PHP
php实现无限级分类(递归方法)
2015/08/06 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
利用JS解决ie6不支持max-width,max-height问题的方法
2014/01/02 Javascript
用Jquery实现滚动新闻
2014/02/12 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
JS使用onerror捕获异常示例
2016/08/03 Javascript
AngularJS 与百度地图的结合实例
2016/10/20 Javascript
微信小程序 表单Form实例详解(附源码)
2016/12/22 Javascript
基于bootstrap的选择框插件icheck
2016/12/23 Javascript
RequireJS 依赖关系的实例(推荐)
2017/01/21 Javascript
js实现图片360度旋转
2017/01/22 Javascript
jQuery实现的背景颜色渐变动画效果示例
2017/03/24 jQuery
详解Vue组件之间的数据通信实例
2017/06/17 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
vue模式history下在iis中配置流程
2019/04/17 Javascript
vue axios post发送复杂对象问题
2019/06/04 Javascript
p5.js临摹旋转爱心
2019/10/23 Javascript
VUE.js实现动态设置输入框disabled属性
2019/10/28 Javascript
vue中实现回车键登录功能
2020/02/19 Javascript
[01:35]2018年度CS GO最佳战队-完美盛典
2018/12/17 DOTA
Python数据处理numpy.median的实例讲解
2018/04/02 Python
对python中数据集划分函数StratifiedShuffleSplit的使用详解
2018/12/11 Python
关于Numpy中的行向量和列向量详解
2019/11/30 Python
Pytorch 使用CNN图像分类的实现
2020/06/16 Python
德国高品质男装及配饰商城:Cultizm(Raw Denim原色牛仔裤)
2018/04/16 全球购物
印度在线杂货店:bigbasket
2018/08/23 全球购物
在使用非全零作为空指针内部表达的机器上, NULL是如何定义
2014/11/09 面试题
C#怎么让一个窗口居中显示?
2015/10/20 面试题
常用UNIX 命令(Linux的常用命令)
2015/12/26 面试题
GMP办公室主任岗位职责
2014/03/14 职场文书
好的促销活动方案
2014/08/21 职场文书
个人四风问题整改措施思想汇报
2014/10/04 职场文书
2015年大学社团工作总结
2015/04/09 职场文书
法人身份证明书
2015/06/18 职场文书