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


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实现的在新窗口打开链接的方法小结
Apr 22 Javascript
基于jquery的气泡提示效果
May 31 Javascript
js如何实现设计模式中的模板方法
Jul 23 Javascript
JavaScript解析json格式数据简单示例
Dec 09 Javascript
javascript中基本类型和引用类型的区别分析
May 12 Javascript
在AngularJS中使用jQuery的zTree插件的方法
Apr 21 Javascript
jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
Jun 12 Javascript
jQuery查找节点方法完整实例
Sep 13 Javascript
JS数组排序方法实例分析
Dec 16 Javascript
原生js实现可爱糖果数字时间特效
Dec 30 Javascript
javascript实现Java中的Map对象功能的实例详解
Aug 21 Javascript
使用eslint和githooks统一前端风格的技巧
Jul 29 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随机生成福彩双色球号码的2种方法
2013/02/04 PHP
ThinkPHP页面跳转success与error方法概述
2014/06/25 PHP
PHP 中常量的知识整理
2017/04/14 PHP
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
js采用map取到id集合组并且实现点击一行选中一行
2013/12/16 Javascript
JavaScript设置body高度为浏览器高度的方法
2015/02/09 Javascript
浅谈javascript中call()、apply()、bind()的用法
2015/04/20 Javascript
需灵活掌握的Bootstrap预定义排版类 你精通吗?
2016/06/20 Javascript
JS button按钮实现submit按钮提交效果
2016/11/01 Javascript
DataTables+BootStrap组合使用Ajax来获取数据并且动态加载dom的方法(排序,过滤,分页等)
2016/11/09 Javascript
ES6通过babel转码使用webpack使用import关键字
2016/12/13 Javascript
jQuery Validate验证框架详解(推荐)
2016/12/17 Javascript
jQuery插件ImgAreaSelect实现头像上传预览和裁剪功能实例讲解一
2017/05/26 jQuery
Node.js学习之TCP/IP数据通讯(实例讲解)
2017/10/11 Javascript
js实现复制功能(多种方法集合)
2018/01/06 Javascript
详解使用JWT实现单点登录(完全跨域方案)
2019/08/02 Javascript
五分钟搞懂Vuex实用知识(小结)
2019/08/12 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
如何利用nodejs自动定时发送邮件提醒(超实用)
2020/12/01 NodeJs
python 将字符串转换成字典dict
2013/03/24 Python
python range()函数取反序遍历sequence的方法
2018/06/25 Python
python通过txt文件批量安装依赖包的实现步骤
2019/08/13 Python
PyCharm2018 安装及破解方法实现步骤
2019/09/09 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
win10下python3.8的PIL库安装过程
2020/06/08 Python
Python爬虫爬取糗事百科段子实例分享
2020/07/31 Python
Python如何解除一个装饰器
2020/08/07 Python
详解canvas多边形(蜘蛛图)的画法示例
2018/01/29 HTML / CSS
欧缇丽加拿大官方网站:Caudalie加拿大
2019/07/18 全球购物
资生堂英国官网:Shiseido英国
2020/12/30 全球购物
请描述一下”is a”关系和”has a”关系
2015/02/03 面试题
Java里面有没有全局变量?为什么?
2015/02/06 面试题
文案策划求职信
2014/03/18 职场文书
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
初中差生评语
2014/12/29 职场文书
Windows Server 版本 20H2 于 8 月 9 日停止支持,Win10 版本 21H1 将于 12 月结束支
2022/07/23 数码科技