uniapp日历组件

<template>
	<view style="overflow-x: hidden;font-size: 12px;">
		<view v-if="isDescShow" class="day_desc">
			<view class="desc_item"><text class="point_blue"></text>全天考勤正常</view>
			<view class="desc_item"><text class="point_orange"></text>当天存在异常:迟到、早退、缺卡</view>
			<view class="desc_item"><text class="point_gray"></text>当天提交过:请假、加班、出差、外出、补卡申请</view>
		</view>
		<view class="day grid_title">
			<uni-grid :column="7" :show-border="false" :square="false">
				<uni-grid-item v-for="(item,index) in ['日','一','二','三','四','五','六']" :index="index" :key="index">
					<text>{{item}}</text>
				</uni-grid-item>
			</uni-grid>
		</view>
		<!-- 日期 -->
		<view 
		    class="threeMonth"    
		    @touchstart="touchstart"
		    @touchmove="touchmove" 
		    @touchend="touchend"
		    :style="'left:calc(-100% + '+ dayLeft + 'px)'"
		>
		    <!-- 遍历集合三个月的列表 -->
		    <view class="day" 
		        v-for="(item,index) in monthList"
		        :key="index"
		    >
				<!-- 遍历每个月的天数 -->
				<uni-grid :column="7" :show-border="false" @change="dayClick">
					<uni-grid-item v-for="(item2,index2) in item" :index="index2" :key="index2">
						<text class="day_default" :class="{'today_bg_color': item2.today, 'today_text': isSelectedDay(item2)}" :style="item2.fromMonth=='nowMonth'?'':'color:#c8c9cc;'">{{item2.day}}</text> 
						<view class="flex_row_center">
							<text class="point_blue"></text>
							<text class="point_orange"></text>
						</view>
					</uni-grid-item>
				</uni-grid>
		    </view>
		</view>
	</view>
</template>

<script>
	export default {
		name:"attendence-calender",
		options: {
			styleIsolation: 'shared'
		},
		props: {
			date: {
				type: Date,
				required: false,
				default: function() {
					return new Date()
				}
			},
			attendenceData: Object
		},
		data() {
			 return {
				isDescShow: true,
				selectedDay: {
					year: 2023,
					month: 1,
					day: 1
				}, // 获取当天
				nowYear: 2023, // 获取年份
				nowMonth: 1, // 获取月份
				monthList:[],
				dayLeft: 0,
				startLeft: 0
			}
		},
		created() {
			/*调用初始化当前考勤*/
			this.initData()
		},
		methods: {
			// 日期模块点击
			touchstart(e){
				// 记录初始点击位置
				this.startLeft = e.touches[0].pageX
			},
			// 日期模块拖动
			touchmove(e){
				this.dayLeft = e.touches[0].pageX - this.startLeft
			},
			// 日期模块松手
			touchend(e){
				// 根据移动距离判断跳转上一月还是下一月
				if(this.dayLeft > 100 ) this.syy()
				if(this.dayLeft < -100) this.xyy()
				this.dayLeft = 0
			},
			/* 初始化数据 */
			initData() {
				this.nowYear = this.date.getFullYear()
				this.nowMonth = this.date.getMonth() + 1
				this.setSelectDay(this.nowYear, this.nowMonth, this.date.getDate())
				this.getThreeMonth()
			},
			isSelectedDay(item) {
				if (item.year == this.selectedDay.year && item.month == this.selectedDay.month
				&& item.day == this.selectedDay.day) {
					return true
				} else {
					return false
				}
			},
			isToday(year, month, day) {
				const now = new Date()
				if (now.getFullYear() == year && (now.getMonth() + 1) == month
					&& now.getDate() == day) {
					return true
				} else {
					return false
				}
			},
			setSelectDay(year, month, day) {
				this.selectedDay = {
					year,
					month,
					day
				}
				// 获取选中日期的考勤数据
				this.$emit("selectDay", this.selectedDay)
			},
			/*获取上一月*/
			syy(){
				if (this.nowMonth == 1){
					this.nowYear = parseInt(this.nowYear) - 1;
					this.nowMonth = 12;
					this.getThreeMonth();
				} else {
					this.nowMonth = parseInt(this.nowMonth) - 1;
					this.getThreeMonth();
				}
				this.setSelectDay(this.nowYear, this.nowMonth, 1)
			},
			/*获取下一月*/
			xyy(){
				if (this.nowMonth == 12){
					this.nowYear = parseInt(this.nowYear) + 1;
					this.nowMonth = 1;
					this.getThreeMonth();
				} else {
					this.nowMonth = parseInt(this.nowMonth) + 1;
					this.getThreeMonth();
				}
				this.setSelectDay(this.nowYear, this.nowMonth, 1)
				return;
			},
			/*闰年 时间判断*/
			isLeap(year) {
				return year % 4 == 0 ? (year % 100 != 0 ? 1 : (year % 400 == 0 ? 1 : 0)) : 0;
			},
			//获取某月日期
			getCalendar(year,month){
				const _this = this
				//每个月的天数
				var days_per_month = new Array(31, 28 + this.isLeap(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 
				var dateList = []; 
				
				//获取本月的一号是星期几 0星期天
				var s = new Date(year + '/' + month + '/' + '01').getDay();
				//上月月份
				var prevMonth = month == 1 ? 12: month - 1
				// 上月年份
				var prevMonthYear = month == 1 ? (year - 1) : year
				// 上月天数
				var prevMonthDay = days_per_month[prevMonth - 1]
				
				// 补上 上月日期
				for(var i = s - 1; i >= 0; i--) {
					var day = parseInt(prevMonthDay)-i;
					dateList.push({
						year:  prevMonthYear,
						month: prevMonth,
						day,
						fromMonth: 'lastMonth',
						today: _this.isToday(prevMonthYear, prevMonth, day)
					})//获取上月末尾天数  补齐本月日历显示
				}
				 
				// 当月天数
				var nowMonthDay = days_per_month[month - 1]
				
				// 添加当月日期
				for(var j = 0; j < nowMonthDay; j ++) {
					dateList.push({
						year: year,
						month: month,
						day: j + 1,
						fromMonth: 'nowMonth',
						today: _this.isToday(year, month, j + 1)
					})
				}
				
				//获取本月最后一天是星期几 0星期天
				var l = new Date(year + '/' + month + '/' + nowMonthDay).getDay();
				// 下月月份
				var lastMonth = month == 12 ? 1: month + 1
				// 下月年份
				var lastMonthYear = month == 12 ? (year + 1) : year
				if(l < 6){
					// 补上 下月日期
					for(var i = 1; i <= 6 - l; i++) {
						dateList.push({
							year: lastMonthYear,
							month: lastMonth,
							day: i,
							fromMonth: 'nextMonth',
							today: _this.isToday(lastMonthYear, lastMonth, i)
						})
					 }
				}
				return dateList
			},
			/**
			 * 通过年份和日历月份获取上个月或者下个月的年份和日历月份,日历月份比真实月份大1
			 * type  0、上个月  1、下个月
			 */
			getCurrentDateInfo(orgYear, orgMonth, type) {
				const result = {}
				// 获取上一月日历
				if (type == 0) {
					if (orgMonth == 1){
						result.year = parseInt(orgYear)-1;
						result.month = 12
					} else {
						result.year = orgYear
						result.month = parseInt(orgMonth)-1;
					}
				} else if (type == 1) {
					if (orgMonth == 12){
						result.year = parseInt(orgYear)+1;
						result.month = 1
					} else {
						result.year = orgYear
						result.month = parseInt(orgMonth)+1;
					}
				}
				return result
			},
			// 获取三月日期
			getThreeMonth(){
				let year,month
				this.monthList = []
				// 获取上一月日历
				const prevDate = this.getCurrentDateInfo(this.nowYear, this.nowMonth, 0)
				this.monthList.push(this.getCalendar(prevDate.year,prevDate.month))
				// 获取当前月日历
				this.monthList.push(this.getCalendar(this.nowYear,this.nowMonth))
				// 获取下一月日历
				const nextDate = this.getCurrentDateInfo(this.nowYear, this.nowMonth, 1)
				this.monthList.push(this.getCalendar(nextDate.year,nextDate.month))
				
			},
			
			//点击某一天
			dayClick(e){
				const index = e.detail.index
				//点击 哪一天
				const selectedItem = this.monthList[1][index]
				let day = selectedItem.day
				this.setSelectDay(selectedItem.year, selectedItem.month, selectedItem.day)
				// 如果 点击本月的日期
				if(selectedItem.fromMonth == 'nowMonth'){
					return
				}
				if(selectedItem.fromMonth == 'nextMonth'){
					// 如果 点击下一月的日期 跳转下一月
					this.xyy()
				} else if(selectedItem.fromMonth == 'lastMonth'){
					// 如果 点击上一月的日期 跳转上一月
					this.syy()
				}
			}
		}
	}
</script>

<style lang="less" scoped>
	.threeMonth {
		display: flex;
		width: 300%;
		position: relative;
	}
	.day {
		display: flex;
		position: relative;
		width: 100%;
		justify-content: space-around;
		flex-wrap: wrap;
		text-align: center;
		align-content: flex-start;
	}
	.day /deep/ .uni-grid-item__box {
		align-items: center;
		justify-content: center;
	}
	.grid_title /deep/ .uni-grid {
		// flex-wrap: nowrap !important; 
	}
	.day_default {
		height: 30px;
		width: 30px;
		line-height: 30px;
		border-radius: 50%;
	}
	.today_text {
		background-color: #3389ef !important;
		color: white !important;
	}
	.today_bg_color {
		color: #3389ef;
		background-color: #3389ef2e;
	}
	.day_desc {
		padding: 10px;
		background-color: #eff2f3;
		border-radius: 4px;
		font-size: 12px;
		margin-bottom: 10px;
	}
	.desc_item {
		display: flex;
		align-items: center;
		line-height: 20px;
	}
	.status_point {
		display: inline-block;
		width: 4px;
		height: 4px;
		border-radius: 50%;
		margin: 2px;
	}
	.point_blue:extend(.status_point) {
		background-color: #3389ef;
	}
	.point_orange:extend(.status_point) {
		background-color: #ffaa00;
	}
	.point_gray:extend(.status_point) {
		background-color: #828387;
	}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值