网络编程
位置:首页>> 网络编程>> JavaScript>> 微信小程序可滑动月日历组件使用详解

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

作者:康彦  发布时间:2024-04-16 10:32:22 

标签:微信小程序,日历组件

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

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

展示一下效果图

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

在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日历插件

来源:https://blog.csdn.net/qq_36082658/article/details/93033155

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com