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


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 相关文章推荐
Javascript 通过json自动生成Dom的代码
Apr 01 Javascript
jQuery 创建Dom元素
May 07 Javascript
jQuery 翻牌或百叶窗效果(内容三秒自动切换)
Jun 14 Javascript
jquery获取所有选中的checkbox实现代码
May 26 Javascript
Vue.js快速入门教程
Sep 07 Javascript
详解webpack打包vue时提取css
May 26 Javascript
ES6学习之变量的两种命名方法示例
Jul 18 Javascript
微信小程序实现图片压缩功能
Jan 26 Javascript
学习Vue组件实例
Apr 28 Javascript
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
Mar 15 Javascript
jquery 时间戳转日期过程详解
Oct 12 jQuery
React 条件渲染最佳实践小结(7种)
Sep 27 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
Thinkphp模板中截取字符串函数简介
2014/06/17 PHP
php简单定时执行任务的实现方法
2015/02/23 PHP
PHP获取昨天、今天及明天日期的方法
2016/02/03 PHP
PHP Smarty模版简单使用方法
2016/03/30 PHP
JavaScript实际应用:innerHTMl和确认提示的使用
2006/06/22 Javascript
不用ajax实现点击文字即可编辑的方法
2007/12/16 Javascript
jQuery为iframe的body添加click事件的实现代码
2011/04/07 Javascript
自定义ExtJS控件之下拉树和下拉表格附源码
2013/10/15 Javascript
js点击出现悬浮窗效果不使用JQuery插件
2014/01/20 Javascript
JavaScript汉诺塔问题解决方法
2015/04/21 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
jquery控制显示服务器生成的图片流
2015/08/04 Javascript
Bootstrap每天必学之按钮(Button)插件
2016/04/25 Javascript
JS表格组件神器bootstrap table详解(强化版)
2016/05/26 Javascript
浅析jQuery中使用$所引发的问题
2016/05/29 Javascript
详解Node.js中的事件机制
2016/09/22 Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
2016/12/07 Javascript
vue表单绑定实现多选框和下拉列表的实例
2017/08/12 Javascript
webpack本地开发环境无法用IP访问的解决方法
2018/03/20 Javascript
详解从0开始搭建微信小程序(前后端)的全过程
2019/04/15 Javascript
小程序实现订单倒计时功能
2019/04/23 Javascript
微信小程序如何实现全局重新加载
2019/06/05 Javascript
JavaScript find()方法及返回数据实例
2020/04/30 Javascript
解决vue2中使用elementUi打包报错的问题
2020/09/22 Javascript
python中matplotlib实现最小二乘法拟合的过程详解
2017/07/11 Python
python使用xpath中遇到:到底是什么?
2018/01/04 Python
一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息
2018/04/17 Python
python单线程文件传输的实例(C/S)
2019/02/13 Python
Python高级特性与几种函数的讲解
2019/03/08 Python
Python利用逻辑回归模型解决MNIST手写数字识别问题详解
2020/01/14 Python
python计算导数并绘图的实例
2020/02/29 Python
python 实现有道翻译功能
2021/02/26 Python
德国网上超市:myTime.de
2019/08/26 全球购物
继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么?
2015/11/18 面试题
单位委托书怎么写
2014/08/02 职场文书
500字作文之关于爸爸
2019/11/14 职场文书