微信小程序可滑动月日历组件
此日历可进行左右滑动,展示签到打卡信息,和大家分享一下。
如果样式变形,请检查是否有共用样式起冲突
展示一下效果图
在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日历插件
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持前端开发者。
评论前必须登录!
注册