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


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实现检测浏览器及版本的脚本代码
Jan 22 Javascript
使用基于jquery的gamequery插件做JS乒乓球游戏
Jul 31 Javascript
JavaScript获取XML数据附示例截图
Mar 05 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
Mar 11 Javascript
JavaScript中的ajax功能的概念和示例详解
Oct 17 Javascript
AngularJS入门教程之数据绑定用法示例
Nov 01 Javascript
一句jQuery代码实现返回顶部效果(简单实用)
Dec 28 Javascript
webpack处理 css\less\sass 样式的方法
Aug 21 Javascript
浅谈Vue数据绑定的原理
Jan 08 Javascript
JS实现遍历不规则多维数组的方法
Mar 21 Javascript
js变量声明var使用与不使用的区别详解
Jan 21 Javascript
layui下拉框获取下拉值(select)的例子
Sep 10 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
全国FM电台频率大全 - 8 黑龙江省
2020/03/11 无线电
php 模拟 asp.net webFrom 按钮提交事件实例
2014/10/13 PHP
Yii中实现处理前后台登录的新方法
2015/12/28 PHP
golang与PHP输出excel示例
2016/07/22 PHP
php-fpm中max_children的配置
2019/03/15 PHP
PHP接入支付宝接口失效流程详解
2020/11/10 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
Javascript 继承机制实例
2009/08/12 Javascript
JavaScript和CSS通过expression实现Table居中显示
2013/06/28 Javascript
jquery UI Datepicker时间控件的使用方法(基础版)
2015/11/07 Javascript
跟我学习javascript的闭包
2015/11/16 Javascript
js运动应用实例解析
2015/12/28 Javascript
Easyui Treegrid改变默认图标的方法
2016/04/29 Javascript
vue2.0开发实践总结之入门篇
2016/12/06 Javascript
原生js开发的日历插件
2017/02/04 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
JS中利用swiper实现3d翻转幻灯片实例代码
2017/08/25 Javascript
JavaScript代码模拟鼠标自动点击事件示例
2020/08/07 Javascript
在项目vue中使用echarts的操作步骤
2020/09/07 Javascript
Python使用requests及BeautifulSoup构建爬虫实例代码
2018/01/24 Python
Python3中关于cookie的创建与保存
2018/10/21 Python
Python3 安装PyQt5及exe打包图文教程
2019/01/08 Python
python使用装饰器作日志处理的方法
2019/07/11 Python
python网络编程 使用UDP、TCP协议收发信息详解
2019/08/29 Python
Pytorch的mean和std调查实例
2020/01/02 Python
Python 从attribute到property详解
2020/03/05 Python
Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
2020/05/11 Python
如何实现一个python函数装饰器(Decorator)
2020/10/12 Python
美国面料纺织品商城:Fabric.com
2017/06/28 全球购物
商务英语本科生的自我评价分享
2013/11/15 职场文书
农村婚礼证婚词
2014/01/08 职场文书
奶茶专卖店创业计划书
2014/01/18 职场文书
推广普通话演讲稿
2014/05/23 职场文书
维护民族团结心得体会2016
2016/01/15 职场文书
怎样做好公众演讲能力?
2019/08/28 职场文书
十大最强飞行系宝可梦,BUG燕上榜,第二是飞行系王者
2022/03/18 日漫