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


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 一个函数对同一元素的多个事件响应
Jul 25 Javascript
javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象
Jan 15 Javascript
JQuery的ajax获取数据后的处理总结(html,xml,json)
Jul 14 Javascript
jQuery实现当按下回车键时绑定点击事件
Jan 28 Javascript
验证码在IE中不刷新而谷歌等浏览器正常的解决方案
Mar 18 Javascript
js中的cookie的读写操作示例详解
Apr 17 Javascript
用svg制作富有动态的tooltip
Jul 17 Javascript
jQuery支持添加事件的日历特效代码分享(3种样式)
Aug 24 Javascript
使用Node.js实现ORM的一种思路详解(图文)
Oct 24 Javascript
SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法
Jan 09 Javascript
解决Vue.js由于延时显示了{{message}}引用界面的问题
Aug 25 Javascript
JavaScript实现10秒后再次获取验证码
Dec 02 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
计数器详细设计
2006/10/09 PHP
PHP array_push 数组函数
2009/12/26 PHP
php数据库密码的找回的步骤
2011/01/12 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
2014/11/14 PHP
php删除数组指定元素实现代码
2017/05/03 PHP
13个绚丽的Jquery 界面设计网站推荐
2010/09/28 Javascript
基于JQuery的Select选择框的华丽变身
2011/08/23 Javascript
JavaScript调用后台的三种方法实例
2013/10/17 Javascript
jquery向上向下取整适合分页查询
2014/09/06 Javascript
jQuery入门基础知识学习指南
2015/08/14 Javascript
微信小程序 加载 app-service.js 错误解决方法
2016/10/12 Javascript
vue使用drag与drop实现拖拽的示例代码
2017/09/07 Javascript
浅谈Webpack自动化构建实践指南
2017/12/18 Javascript
Angular简单验证功能示例
2017/12/22 Javascript
vue项目中公用footer组件底部位置的适配问题
2018/05/10 Javascript
微信小程序扫描二维码获取信息实例详解
2019/05/07 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
python获取标准北京时间的方法
2015/03/24 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
python抓取搜狗微信公众号文章
2019/04/01 Python
python导入坐标点的具体操作
2019/05/10 Python
Python3基础教程之递归函数简单示例
2019/06/07 Python
Django 响应数据response的返回源码详解
2019/08/06 Python
Python 实用技巧之利用Shell通配符做字符串匹配
2019/08/23 Python
python itsdangerous模块的具体使用方法
2020/02/17 Python
微软日本官方网站:Microsoft日本
2017/11/26 全球购物
新锐科技Java程序员面试题
2016/07/25 面试题
市场开发与营销专业求职信
2013/12/31 职场文书
幼师自我鉴定
2014/02/01 职场文书
社区班子对照检查材料
2014/08/27 职场文书
民事答辩状范本
2015/05/21 职场文书
小学教育见习总结
2015/06/23 职场文书
领导莅临指导欢迎词
2015/09/30 职场文书
python解决12306登录验证码的实现
2021/04/18 Python
springboot入门 之profile设置方式
2022/04/04 Java/Android
Python加密与解密模块hashlib与hmac
2022/06/05 Python