移动端手写日历(以uniapp为例)、展开收起可切换月份或周、可复制直接用(箭头需自己找图片)。

文章描述了一个使用Vue.js编写的日历组件,可以实时展示当前月份和日期,支持切换上下一周和月份,同时包括日期选择和事件处理功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
    <view>
        <view class="calendar">
			<view class="calendar-top flex-between">
				<view @click="preNextDate(0)"><span class="iconfont">&#xe660;</span>{{ monthShow ? '上一月' : '上一周' }}</view>
				<view>{{year}}年{{month}}月</view>
				<view @click="preNextDate(1)">{{ monthShow ? '下一月' : '下一周' }}<span class="iconfont">&#xe65f;</span></view>
			</view>
			<view class="calendar-bottom">
				<view class="week-item" v-for="(item,index) in weekList" :key="index">
					{{item}}
				</view>
				<view v-for="(item, index) in everyDay" :key="item.day" class="day-box flex-center" :class="nowDay > item.date ? 'grayDate' : ''" v-if="monthShow">
					<view class="day-item" :class="selectDay == item.date ? 'daySelect' : ''" @click="changeDate(item.date)">
						{{ nowDay== item.date ? '今日' : item.day }}
						<view class="day-point" v-if="item.day && selectDay != item.date"></view>
					</view>
				</view>
				
				<view v-for="(item, index) in weekDates" :key="index" class="day-box flex-center" :class="nowDay > getNowTime(item) ? 'grayDate' : ''" v-if="!monthShow">
					<view class="day-item" :class="selectDay == getNowTime(item) ? 'daySelect' : ''" @click="changeDate(getNowTime(item))">
						{{ nowDay == getNowTime(item) ? '今日' : getNowTime(item).slice(-2) }}
						<view class="day-point" v-if="item && selectDay != getNowTime(item)"></view>
					</view>
				</view>
				<view class="iconfont" @click="changeWeekMonth">{{ monthShow ? '&#xe672;' : '&#xe679;' }}</view>
			</view>
		</view>
    </view>
</template>

<style scoped lang="scss">
    view{
		box-sizing: border-box;
	}
	.calendar{
		padding: 0 26rpx;
		
		.calendar-top{
			height: 109rpx;
			font-size: 27rpx;
			font-family: PingFang SC;
			font-weight: 500;
			color: #000000;
			
			view:nth-child(2){
				font-size: 31rpx;
			}
			
			.iconfont{
				font-size: 25rpx;
				vertical-align: inherit;
			}
		}
		
		.calendar-bottom{
			display: flex;
			flex-wrap: wrap;
			padding: 33rpx 0 60rpx;
			width: 697rpx;
			height: auto;
			background: #FFFFFF;
			border-radius: 20rpx;
			position: relative;
			
			.week-item{
				width: 14%;
				text-align: center;
				font-size: 24rpx;
				font-family: PingFang SC;
				font-weight: 500;
				color: #666666;
			}
			
			.day-box{
				width: 14%;
				height: 100rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				
				.day-item{
					font-size: 29rpx;
					font-family: PingFang SC;
					font-weight: 500;
					color: #000000;
					
					.day-point{
						width: 5rpx;
						height: 5rpx;
						background: #FF3615;
						border-radius: 50%;
						margin: 5rpx auto 0;
					}
				}
				
				.daySelect{
					width: 80rpx;
					height: 80rpx;
					text-align: center;
					line-height: 80rpx;
					background: #45CFF5;
					font-size: 29rpx;
					font-family: PingFang SC;
					font-weight: 500;
					color: #FFFFFF;
					border-radius: 50%;
				}
			}
			
			.grayDate{
				.day-item{
					color: #999999;
					
					.day-point{
						background: #CCCCCC;
					}
				}
			}
			
			.iconfont{
				color: rgba(136, 136, 136, 1);
				font-size: 28rpx;
				position: absolute;
				left: 50%;
				right: 0;
				margin-left: -18rpx;
				bottom: 36rpx;
			}
		}
	}
</style>
<script>
    export default {
        data() {
            return {
				weekList: ['日', '一', '二', '三', '四', '五', '六'],
                monthShow: false,
                year: 0,
				month: 0,
				day: 0,
				week: '',
                nowDay: '',
				selectDay: '',
                everyDay: [],
				weekDates: [],
            }
        },
        onLoad() {
            this.year = Number(this.getNowTime(new Date(), 2).slice(0, 4));
			this.month = Number(this.getNowTime(new Date(), 2).slice(5, 7));
			this.day = Number(this.getNowTime(new Date(), 2).slice(8, 10));
			this.nowDay = this.getNowTime(new Date())
			this.selectDay = this.getNowTime(new Date())
			if(uni.getSystemInfoSync().platform == 'ios'){
				this.getEveryDay(this.year + '/' + this.month + '/' + this.day);
			}else{
				this.getEveryDay(this.year + '-' + this.month);
			}
			this.getWeekDates(new Date())
        },
        methods: {
            // 获取当前日期
            getNowTime(time, type) {
				var date = time,
					year = date.getFullYear(),
					month = date.getMonth() + 1,
					day = date.getDate(),
					hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(),
					minute = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(),
					second = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
				month >= 1 && month <= 9 ? (month = "0" + month) : "";
				day >= 0 && day <= 9 ? (day = "0" + day) : "";
				if (type == 1) {
					if(uni.getSystemInfoSync().platform == 'ios'){
						var timer = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second;
					}else{
						var timer = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
					}
				} else {
					var timer = year + '/' + month + '/' + day;
				}
				
				return timer;
			},
            // 遍历月份日期
			getEveryDay(data) {
				let date = new Date(data);
				let month = date.getMonth();
				//设置月份
				date.setMonth(month + 1);
				//设置一个月的某一天-这里设置为零则取到的日期中的天就会是当月的最后一天(比如,二月份就是28或29,其他月份就是30或31),方便下边的循环
				date.setDate(0);
				let dayArry = [];
				let day = date.getDate(); //获取当前月最后一天是几号
				for (let i = 1; i <= day; i++) {
					date.setDate(i); //如果只获取当前选择月份的每一天,则不需要date.setDate(i)只需dayArry.push(i)即可,其中date.setDate(i)是设置当前月份的每一天
					dayArry.push({ day: i, week: this.getWeekday(date.getDay()), date: this.getNowTime(date) }); //选中月份的每一天和当天是星期几
				}
	
				this.everyDay = dayArry;
				this.resetDay();
			},
            getWeekday(day) {
				return ['日', '一', '二', '三', '四', '五', '六'][day];
			},
			//重置日期与顶部周期相对应
			resetDay() {
				let arr = this.weekList;
				let w = this.everyDay[0].week;
				arr.forEach((v, index) => {
					if (v == w) {
						let id = index;
						if (id != 0) {
							for (let i = 0; i < id; i++) {
								this.everyDay.unshift({ day: '', week: '' });
							}
						}
					}
				});
			},
            // 获取周
			getWeekDates(day){
				const currentDayOfWeek = day.getDay(); // 获取今天是星期几( 0 = 周日,...6 = 周六
				const startDate = new Date(day);
				startDate.setDate(day.getDate() - currentDayOfWeek);
				const weekDates = [];
				for (let i = 0; i < 7; i++) {
					const date = new Date(startDate);
					date.setDate(startDate.getDate() + i);
					weekDates.push(date)
				}
				this.weekDates = weekDates
			},
            // 切换上一周月、下一周月
            preNextDate(e){
				if(this.monthShow){
					if(e){
						// 下一月
						this.month += 1;
						if (this.month > 12) {
							this.year += 1;
							this.month = 1;
						}
						if(uni.getSystemInfoSync().platform == 'ios'){
							this.getEveryDay(this.year + '/' + this.month + '/' + 1);
						}else{
							this.getEveryDay(this.year + '-' + this.month);
						}
					}else{
						// 上一月
						this.month -= 1;
						if (this.month == 0) {
							this.year -= 1;
							this.month = 12;
						}
						if(uni.getSystemInfoSync().platform == 'ios'){
							this.getEveryDay(this.year + '/' + this.month + '/' + 1);
						}else{
							this.getEveryDay(this.year + '-' + this.month);
						}
					}
				}else{
					if(e){
						// 下一周
						this.getNextWeekDates()
					}else{
						// 上一周
						this.getPreviousWeekDates()
					}
				}
			},
            getPreviousWeekDates() {
				const today = this.weekDates[0]
			    const previousWeekStartDate = new Date(today);
			    previousWeekStartDate.setDate(today.getDate() - 7); // 上周的开始日期
			
			    const previousWeekDates = [];
			    for (let i = 0; i < 7; i++) {
			        const date = new Date(previousWeekStartDate);
			        date.setDate(previousWeekStartDate.getDate() + i);
			        previousWeekDates.push(date);
			    }
			
			    this.weekDates = previousWeekDates;
				this.year = Number(this.getNowTime(this.weekDates[0], 2).slice(0, 4));
				this.month = Number(this.getNowTime(this.weekDates[0], 2).slice(5, 7));
			},
			getNextWeekDates() {
				const today = this.weekDates[0]
			    const nextWeekStartDate = new Date(today);
			    nextWeekStartDate.setDate(today.getDate() + 7); // 下周的开始日期
			
			    const nextWeekDates = [];
			    for (let i = 0; i < 7; i++) {
			        const date = new Date(nextWeekStartDate);
			        date.setDate(nextWeekStartDate.getDate() + i);
			        nextWeekDates.push(date);
			    }
			
			    this.weekDates = nextWeekDates;
				this.year = Number(this.getNowTime(this.weekDates[0], 2).slice(0, 4));
				this.month = Number(this.getNowTime(this.weekDates[0], 2).slice(5, 7));
			},
            // 更换周/月
			changeWeekMonth() {
				this.monthShow = !this.monthShow

                this.month = Number(this.selectDay.slice(5, 7));

                if(this.monthShow) {
                    this.year = Number(this.selectDay.slice(0, 4))
                    if(uni.getSystemInfoSync().platform == 'ios'){
                	    this.getEveryDay(this.year + '/' + this.month + '/' + 1);
                    }else{
                	    this.getEveryDay(this.year + '/' + this.month);
                    }
                } else {
                    this.getWeekDates(new Date(this.selectDay))
                }
			},
			// 选中日期
			changeDate(item){
				if(this.nowDay <= item ){
					this.year = Number(item.slice(0, 4));
					this.month = Number(item.slice(5, 7));
					this.day = Number(item.slice(8, 10));
					this.selectDay = item
				}
			},
        }
    }
</script>

有问题欢迎大家随时提,谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值