uniapp+uview模仿企业微信请假时间选择器

其中第一项年月日周只显示当前年份和上一年,下一年的时间,当前年份只显示月日周

第二项为小时,第三项为分钟

下面是timeSelect组件代码 (请结合uview1.0)

html 复制代码
<template>
	<u-popup v-model="value" :mask-close-able="false" mode="bottom" safe-area-inset-bottom border-radius="32" @close="cancelClick">
		<view class="select-time u-p-t-20">
			<view class="space-between select-heard">
				<view class="heard-btn h-100 flex-center u-f-28 w-s-color-A" @click="cancelClick">取消</view>
				<view class="heard-title h-100 flex-center w-s-color-0 u-f-32">选择时间</view>
				<view class="heard-btn h-100 flex-center text-primary u-f-28 font-weight-550" @click="confirmClick">确定</view>
			</view>
			<picker-view :value="timeValue" @change="bindChange" indicator-class="indicator" class="picker-view">
				<picker-view-column>
					<view class="item" :class="[{'year-item':item.status == 0},{'active-item':index==bindValue[0] || index==timeValue[0]}]"  v-for="(item, index) in years" :key="index">{{ item.time }}</view>
				</picker-view-column>
				<picker-view-column>
					<view class="item" :class="[{'active-item':index==bindValue[1] || index==timeValue[1]}]" v-for="(item, index) in hours" :key="index">{{ item }}</view>
				</picker-view-column>
				<picker-view-column>
					<view class="item" :class="[{'active-item':index==bindValue[2] || index==timeValue[2]}]" v-for="(item, index) in minutes" :key="index">{{ item }}</view>
				</picker-view-column>
			</picker-view>
		</view>
	</u-popup>
</template>
javascript 复制代码
<script>
export default {
	props: {
		// 是否显示Modal
		value: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			/* 选择时间相关 */
			hours: [], //小时
			minutes: [], //分钟
			years: [], //年月日周
			timeValue: [], //默认选中的时间
			bindValue: [] //选中的时间
		};
	},
	mounted() {
		this.generateDateArray();
	},
	methods: {
		/*时间相关 获取年月日周 */
		generateDateArray() {
			const dateArray = [];
			const now = new Date();
			const currentYear = now.getFullYear(); // 获取当前年份
			const startDate = new Date(currentYear - 1, 0, 1); // 前一年的1月1日
			const endDate = new Date(currentYear + 1, 11, 31); // 后一年的12月31日

			const weekdays = ['日', '一', '二', '三', '四', '五', '六']; // 周几的中文映射

			// 遍历从 startDate 到 endDate 的每一天
			for (let date = startDate; date <= endDate; date.setDate(date.getDate() + 1)) {
				const year = date.getFullYear();
				const month = date.getMonth() + 1; // 月份从0开始,需要+1
				const day = date.getDate();
				const weekday = weekdays[date.getDay()]; // 获取周几
				let status = 0;
				let formattedDate;
				// 如果是当前年份,去掉年份显示
				if (year === currentYear) {
					formattedDate = `${month}月${day}日周${weekday}`;
					status = 1;
				} else {
					formattedDate = `${year}年${month}月${day}日周${weekday}`;
				}
				const activeTime = `${year}-${month}-${day}`;
				dateArray.push({
					time: formattedDate,
					status,
					activeTime
				});
			}
			this.years = dateArray;
			let month = now.getMonth() + 1; // 月份从0开始,需要+1
			let day = now.getDate();
			let newYear = currentYear + '-' + month + '-' + day;
			
			// 获取当前小时(0-23)
			const currentHour = now.getHours() < 10 ? `0${now.getHours()}` : now.getHours();

			/* 小时 */
			const hoursArray = Array.from({ length: 24 }, (_, i) => {
				return i < 10 ? `0${i}` : `${i}`;
			});
			
			// 获取当前分钟(0-59)
			const currentMinute = now.getMinutes()<10 ? `0${now.getMinutes()}` : now.getMinutes();
			/* 分钟 */
			const minutesArray = Array.from({ length: 60 }, (_, i) => {
				return i < 10 ? `0${i}` : `${i}`;
			});
			
			this.hours = hoursArray;
			this.minutes = minutesArray;
			this.$nextTick(()=>{
				dateArray.map((item, index) => {
					if (item.activeTime == newYear) {
						this.$set(this.timeValue, 0, index);
					}
				});
				hoursArray.map((item,index)=>{
					if (item == currentHour) {
						this.$set(this.timeValue, 1, index);
					}
				})
				minutesArray.map((item,index)=>{
					if (item == currentMinute) {
						this.$set(this.timeValue, 2, index);
					}
				})
			})
		},
		bindChange(e) {
			this.bindValue = e.detail.value;
		},
		cancelClick() {
			this.$emit('input', false);
		},
		confirmClick() {
			let yearText = this.bindValue.length > 0 ? this.years[this.bindValue[0]].activeTime : this.years[this.timeValue[0]].activeTime;
			let hourText = this.bindValue.length > 0 ? this.hours[this.bindValue[1]] : this.hours[this.timeValue[1]];
			let minuteText = this.bindValue.length > 0 ? this.minutes[this.bindValue[2]] : this.minutes[this.timeValue[2]];
			let timeText = yearText + ' ' + hourText + ':' + minuteText;
			this.$emit('confirmClick', timeText);
		}
	}
};
</script>
css 复制代码
<style lang="scss" scoped>
.select-time {
	.select-heard {
		height: 84rpx;
		.heard-btn {
			width: 25%;
		}
		.heard-title {
			width: 50%;
		}
	}
	.picker-view {
		width: 100%;
		height: 500rpx;
		margin-top: 20rpx;
		.item {
			line-height: 100rpx;
			text-align: center;
			font-size: 30rpx;
		}
		.year-item {
			font-size: 20rpx;
		}
		.active-item{
			color:#333;
			font-weight: 600;
		}
	}
	/deep/.indicator {
		height: 100rpx;
		border-top: 2rpx solid #f0f0f0;
		border-bottom: 2rpx solid #f0f0f0;
	}
}
</style>

在页面中使用,下面的处理逻辑是我要处理开始时间和结束时间的,不需要可自行删除

html 复制代码
<TimeSelect v-model="timeShow" @confirmClick="confirmClick" />
javascript 复制代码
confirmClick(e) {
			this.timeShow = false;
			this.timeType == 1 ? (this.query.start_time = e) : (this.query.end_time = e);
			/* 当开始时间和结束时间都存在的时候判断开始时间是否小于结束时间 */
			if (this.query.start_time && this.query.end_time) {
				let dateA = new Date(this.query.start_time);
				let dateB = new Date(this.query.end_time);
				if (dateA > dateB) {
					this.timeLength=0
					this.dateShow = true;
					this.$refs.uTips.show({
						title: '开始时间必须小于结束时间',
						type: 'error',
						duration: '2300'
					});
				} else {
					this.dateShow = false;
					// 计算时间差(毫秒)
					let timeDifference = dateB - dateA;
					// 将时间差转换为分钟
					let minutesDifference = timeDifference / (1000 * 60);
					let b = 60;
					let c = minutesDifference / b;

					// 将结果乘以10,保留一位小数(变为整数部分)
					let temp = c * 10;

					// 使用Math.ceil进行向上取整
					let roundedUp = Math.ceil(temp);

					// 再除以10,还原为保留一位小数的结果
					this.timeLength = roundedUp / 10;
				}
			}
		},

相关推荐
vx-bot55566610 小时前
企业微信接口在多租户SaaS平台中的集成架构与数据隔离实践
大数据·架构·企业微信
郑州光合科技余经理18 小时前
可独立部署的Java同城O2O系统架构:技术落地
java·开发语言·前端·后端·小程序·系统架构·uni-app
雪芽蓝域zzs19 小时前
uniapp 取消滚动条
uni-app
vx-bot55566619 小时前
企业微信接口在混合云环境下的集成架构与网络互联方案企业微信接口在混合云环境下的集成架构与网络互联方案
网络·架构·企业微信
2401_8658548820 小时前
Uniapp和Flutter哪个更适合企业级开发?
flutter·uni-app
雪芽蓝域zzs20 小时前
uniapp 省市区三级联动
前端·javascript·uni-app
总爱写点小BUG20 小时前
UniApp 图标方案终极排坑:告别 FontClass,拥抱真 SVG 组件化
前端框架·uni-app
Rysxt_2 天前
UniApp获取安卓系统权限教程
android·uni-app
王者鳜錸2 天前
企业微信自动化发消息-从0到1开发实践
运维·自动化·企业微信
木子啊2 天前
ProCamera 智能水印相机解决方案 (UniApp)
数码相机·uni-app·水印相机·小程序水印