uniapp小程序自定义日历(签到、补签功能)

1、切换月份根据当前月判断,只能切换当前月份之前的时间。

2、补卡功能,根据后台设置自己写上即可,可补签多少天。

3、点击签到是签到当前天的,不能指定签到时间。

备注:当前代码只构建了排版样式和切换月份功能,签到状态根据个人开发以及接口返回的详细内容再次处理。

javascript 复制代码
<template>
	<view class="sign-in">

		<view class="sign-in-date">
			<view>今日签到 <text
					style="color: #F05C1C;display: inline-block;margin-left: 15rpx;margin-right: 15rpx;">18积分</text> 待领取
			</view>

			<view>
				<view class="date-icon" @click="LastMonth">
					<image src="/static/left-Date.png" style="width: 100%;height: 100%;"></image>
				</view>
				<text>{{DateTitle}}</text>
				<view class="date-icon">
					<image src="/static/right-Date.png" style="width: 100%;height: 100%;" @click="NextMonth"
						v-if="!hideDateIcon"></image>
				</view>
			</view>

			<view>
				<view>
					<view class="week" v-for="(item,index) in weekFor" :key="index">{{item}}</view>
				</view>
				<view>
					<view class="date" v-for="(item,index) in DateFor" :key="index">
						<image src="/static/success-QD.png" class="SuccessCss" v-if="item==22"></image>
						<image src="/static/error-QD.png" class="SuccessCss" v-if="item==21"></image>
						<text v-if="item!==22 && item!==21">{{item}}</text>
					</view>
				</view>
			</view>

			<view>签到</view>

		</view>

	</view>
</template>

<script>
	export default {
		data() {
			return {
				weekFor: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
				DateTitle: '',
				MeDateTitle: '',
				DateFor: [],
				hideDateIcon: false
			}
		},
		onShow() {
			const currentDate = new Date();
			const year = currentDate.getFullYear();
			const month = currentDate.getMonth() + 1; // getMonth() 返回的月份是从0开始的,所以要加1  
			const day = currentDate.getDate();
			const formattedDate = `${year}年${month}月`;
			const daysInMonth = new Date(year, month, 0).getDate(); // 0代表上一个月的最后一天  
			const firstDayOfMonth = new Date(year, month - 1, 1); // month - 1 因为月份是从0开始的  
			const firstDayOfWeek = firstDayOfMonth.getDay(); // 0=周日, 1=周一, ..., 6=周六  
			const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
			const firstDayOfWeekStr = daysOfWeek[firstDayOfWeek];
			console.log(`当前日期: ${formattedDate}`);
			this.DateTitle = ` ${formattedDate}`
			this.MeDateTitle = ` ${formattedDate}`
			console.log(`该月份的天数: ${daysInMonth}天`);
			this.DateFor = []
			for (let i = 1; i <= daysInMonth; i++) {
				this.DateFor.push(i);
			}
			console.log(`今天是: ${day}号`);
			console.log(`当前月份的第一天是: ${firstDayOfWeekStr}`);
			const emptyDaysMap = {
				'周一': 0,
				'周二': 1,
				'周三': 2,
				'周四': 3,
				'周五': 4,
				'周六': 5,
				'周日': 6
			};
			const emptyDaysCount = emptyDaysMap[firstDayOfWeekStr];
			for (let i = 0; i < emptyDaysCount; i++) {
				this.DateFor.unshift('');
			}
			this.checkDate();
		},
		methods: {
			//上个月
			LastMonth() {
				const [year, month] = this.DateTitle.split('年').map(part => part.replace('月', ''));
				const date = new Date(year, month - 1);
				date.setMonth(date.getMonth() - 1);
				const newYear = date.getFullYear();
				const newMonth = date.getMonth() + 1;
				this.DateTitle = `${newYear}年${newMonth}月`;
				this.getMonthInfo(); // 获取当前月份的信息   
			},
			//下个月
			NextMonth() {
				const [year, month] = this.DateTitle.split('年').map(part => part.replace('月', ''));
				const date = new Date(year, month - 1);
				date.setMonth(date.getMonth() + 1);
				const newYear = date.getFullYear();
				const newMonth = date.getMonth() + 1; // 获取新的月份,注意要加1  
				this.DateTitle = `${newYear}年${newMonth}月`;
				this.getMonthInfo(); // 获取当前月份的信息  
			},
			getMonthInfo() {
				const [year, month] = this.DateTitle.split('年').map(part => part.replace('月', ''));
				const numDays = new Date(year, month, 0).getDate(); // 获取当前月份的天数  
				const firstDay = new Date(year, month - 1, 1).getDay(); // 获取当前月份第一天是星期几  

				console.log(`当前月份有 ${numDays} 天,第一天是星期 ${firstDay === 0 ? '日' : firstDay}`);
				this.DateFor = [];
				for (let i = 1; i <= numDays; i++) {
					this.DateFor.push(i);
				}
				const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
				const firstDayOfWeekStr = daysOfWeek[firstDay]; // 获取第一天的星期几字符串  
				// 计算空白天数  
				const emptyDaysMap = {
					'周一': 0,
					'周二': 1,
					'周三': 2,
					'周四': 3,
					'周五': 4,
					'周六': 5,
					'周日': 6,
				};
				const emptyDaysCount = emptyDaysMap[firstDayOfWeekStr]; // 获取空白天数  
				for (let i = 0; i < emptyDaysCount; i++) {
					this.DateFor.unshift('');
				}

				this.checkDate();
			},
			checkDate() {
				const meDateParts = this.MeDateTitle.match(/(\d+)年(\d+)月/);
				const dateParts = this.DateTitle.match(/(\d+)年(\d+)月/);
				if (meDateParts && dateParts) {
					const meYear = meDateParts[1];
					const meMonth = meDateParts[2];
					const dateYear = dateParts[1];
					const dateMonth = dateParts[2];
					// 判断是否为同一年月  
					this.hideDateIcon = (meYear === dateYear && meMonth === dateMonth);
				}
			},
		}
	}
</script>

<style lang="scss">
	.sign-in {
		width: 100vw;
		min-height: 100vh;
		float: left;
		background: #0F0817;

		.sign-in-date {
			width: 702rpx;
			border-radius: 24rpx;
			margin: 0 auto;
			background: linear-gradient(161deg, #1B1B24 29%, rgba(240, 92, 28, 0.33) 100%);
			padding-top: 32rpx;
			padding-bottom: 32rpx;
		}

		.sign-in-date>view:nth-child(1) {
			width: 654rpx;
			height: 30rpx;
			margin: 0 auto;
			display: flex;
			align-items: center;
			color: #FFFFFF;
			font-size: 24rpx;
		}

		.sign-in-date>view:nth-child(2) {
			width: 654rpx;
			height: 30rpx;
			margin: 49rpx auto 0;
			display: flex;
			align-items: center;
			justify-content: space-between;
			font-family: Akkurat Pro, Akkurat Pro;
			font-weight: bold;
			font-size: 28rpx;
			color: #FFFFFF;

			.date-icon {
				width: 44rpx;
				height: 44rpx;
				text-align: center;
				line-height: 44rpx;
			}
		}

		.sign-in-date>view:nth-child(3) {
			width: 654rpx;
			margin: 40rpx auto 0;
		}

		.sign-in-date>view:nth-child(3)>view:nth-child(1) {
			width: 100%;
			height: 93.4rpx;
			display: flex;
			align-items: center;

			.week {
				width: 93.4rpx;
				height: 93.4rpx;
				text-align: center;
				line-height: 93.4rpx;
				font-family: Akkurat Pro, Akkurat Pro;
				font-weight: bold;
				font-size: 24rpx;
				color: #FFFFFF;
			}
		}

		.sign-in-date>view:nth-child(3)>view:nth-child(2) {
			width: 100%;
			display: flex;
			align-items: center;
			flex-wrap: wrap;

			.date {
				width: 93.4rpx;
				height: 93.4rpx;
				text-align: center;
				line-height: 93.4rpx;
				font-family: Akkurat Pro, Akkurat Pro;
				font-weight: bold;
				font-size: 24rpx;
				color: #FFFFFF;
				display: flex;
				align-items: center;
				justify-content: center;

				.SuccessCss {
					width: 55rpx;
					height: 55rpx;
					text-align: center;
					line-height: 55rpx;
				}
			}
		}

		.sign-in-date>view:nth-child(4) {
			width: 654rpx;
			height: 88rpx;
			background: #F05C1C;
			border-radius: 59rpx;
			text-align: center;
			line-height: 88rpx;
			font-family: PingFang HK, PingFang HK;
			font-weight: 600;
			font-size: 32rpx;
			color: #FFFFFF;
			margin: 50rpx auto 0;
		}
	}
</style>
相关推荐
爱上大树的小猪1 小时前
微信小程序模仿快播标签云滚动特效
微信小程序·小程序
一个处女座的程序猿O(∩_∩)O2 小时前
Uniapp 开发中遇到的坑与注意事项:全面指南
uni-app
Elena_Lucky_baby2 小时前
uniapp 网络请求封装(uni.request 与 uView-Plus)
uni-app
從南走到北6 小时前
挪车小程序挪车二维码php+uniapp
微信小程序·小程序·开源·微信公众平台
烂蜻蜓6 小时前
Uniapp 设计思路全分享
前端·css·vue.js·uni-app·html
Elena_Lucky_baby6 小时前
uniapp封装请求
uni-app
尚学教辅学习资料7 小时前
基于SpringBoot+Vue+uniapp的高校招聘小程序+LW参考示例
spring boot·uni-app·招聘系统
黑云压城After7 小时前
小程序(物流、快递),接入GPS北斗获取路线以及当前车辆位置
小程序
万岳科技程序员小金8 小时前
互联网医院系统源码解析:如何开发智能化的电子处方小程序?
小程序·app开发·互联网医院系统源码·智慧医疗小程序·医院app