uniapp vue3 封装picker时间选择器 年月日时分秒

1、因为在uniapp中并没有完整的年月日时分秒,所以需要自己写一个组件常用

2、 封装好的组件实际效果

完整代码展示

confirmPickDate 在其他方法是改变后数据

用组件ref调用open(val) 是默认赋值回显

javascript 复制代码
<template>
	<view class="dateTimePicker-container">
		<view class="date-time" v-if="visible">
			<view class="mask" @click.stop="close" />
			<view class="box">
				<view class="header">
					<view class="determine" @click.stop="close">取消</view>
					<view class="determine" @click.stop="confirm" :style="{color: themes.theme1 || '#FF4E09',}">确定
					</view>
				</view>

				<picker-view :indicator-style="indicatorStyle" :value="pickerValue" @change="bindChange"
					class="picker-view">
					<picker-view-column>
						<view class="item" v-for="(item,index) in years" :key="index">{{item}}年</view>
					</picker-view-column>
					<picker-view-column>
						<view class="item" v-for="(item,index) in months" :key="index">{{item}}月</view>
					</picker-view-column>
					<picker-view-column>
						<view class="item" v-for="(item,index) in days" :key="index">{{item}}日</view>
					</picker-view-column>
					<picker-view-column>
						<view class="item" v-for="(item,index) in hours" :key="index">{{item}}时</view>
					</picker-view-column>
					<picker-view-column>
						<view class="item" v-for="(item,index) in minutes" :key="index">{{item}}分</view>
					</picker-view-column>
					<picker-view-column>
						<view class="item" v-for="(item,index) in seconds" :key="index">{{item}}秒</view>
					</picker-view-column>
				</picker-view>
			</view>
		</view>

	</view>
</template>

<script setup>
	import {
		ref,
		watch,
		getCurrentInstance,
		defineProps,
		onMounted
	} from 'vue'
	const emits = defineEmits(["confirmPickDate"]);


	let years = ref([]),
		year = ref(null),
		months = ref([]),
		month = ref(null),
		days = ref([]),
		day = ref(null),
		hours = ref([]),
		hour = ref(null),
		minutes = ref([]),
		minute = ref(null),
		second = ref(null),
		seconds = ref([]),
		pickerValue = ref([]),
		indicatorStyle = ref('height: 50px;'),
		timeValue = ref(''),
		visible = ref(false)


	// const {
	// 	proxy
	// } = getCurrentInstance();

	let props = defineProps({
		themes: {
			type: Object,
			default () {
				return {}
			}
		},
		interviewTime: {
			type: String,
			default: ''
		}
	})

	onMounted(() => {
		init()

	})


	const init = (interviewTime) => {
		const date = interviewTime ? new Date(interviewTime) : new Date();
		const Years = []
		const Year = date.getFullYear()
		const Months = []
		const Month = date.getMonth() + 1
		const Days = []
		const Day = date.getDate()
		const Hours = []
		const Hour = date.getHours()
		const Minutes = []
		const Minute = date.getMinutes()
		const Seconds = []
		const Second = date.getSeconds()

		let isDay = 30;
		if (Month == 2) {
			if ((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0)) {
				console.log('闰年')
				isDay = 29;
			} else {
				isDay = 28;
				console.log('平年')
			}
		} else if ([1, 3, 5, 7, 8, 10, 12].includes(Month)) {
			isDay = 31;
		} else {
			isDay = 30;
		}

		for (let i = date.getFullYear() - 100; i <= date.getFullYear() + 100; i++) {
			Years.push(i)
		}
		for (let i = 1; i <= 12; i++) {
			Months.push(i)
		}
		for (let i = 1; i <= isDay; i++) {
			Days.push(i)
		}
		for (let i = 0; i <= 23; i++) {
			if (i < 10) {
				Hours.push('0' + i)
			} else {
				Hours.push(i)
			}
		}
		for (let i = 0; i <= 59; i++) {
			if (i < 10) {
				Minutes.push('0' + i)
				Seconds.push('0' + i)
			} else {
				Minutes.push(i)
				Seconds.push(i)
			}
		}

		years.value = Years
		year.value = Year
		months.value = Months
		month.value = Month
		days.value = Days
		day.value = Day
		hours.value = Hours
		hour.value = Hour
		minutes.value = Minutes
		minute.value = Minute
		seconds.value = Seconds
		second.value = Second
		pickerValue.value = [Years.indexOf(Year), Month - 1, Day - 1, Hour, Minute, second]
		return pickerValue.value
	}


	const bindChange = (e) => {
		const val = e.detail.value

		let Year = years.value[val[0]]
		let isDay = 30,
			Days = [];
		if (val[1] + 1 == 2) {
			if ((val[0] % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0)) {
				console.log('闰年')
				isDay = 29;
			} else {
				isDay = 28;
				console.log('平年')
			}
		} else if ([1, 3, 5, 7, 8, 10, 12].includes(val[1] + 1)) {
			isDay = 31;
		} else {
			isDay = 30;
		}

		for (let i = 1; i <= isDay; i++) {
			Days.push(i)
		}
		days.value = Days;
		year.value = years.value[val[0]]
		month.value = months.value[val[1]]
		day.value = days.value[val[2]]
		hour.value = hours.value[val[3]]
		minute.value = minutes.value[val[4]]
		second.value = seconds.value[val[5]]

	}

	const padZeroStr = (originStr) => {
		if (+originStr < 10) {
			return String(originStr).padStart(2, '0')
		}
		return originStr + ''

	}
	const close = () => {
		visible.value = false
	}

	//val时回显
	const open = (val) => {
		visible.value = true
		if (val !== "" && val) {
			// 调用convertDateString处理val,获取年份和其他值
			const [yearVal, monthVal, dayVal, hourVal, minuteVal, secondVal] = convertDateString(val);
			// 更新year.value和pickerValue
			year.value = yearVal;
			pickerValue.value = [years.value.indexOf(yearVal), monthVal, dayVal, hourVal, minuteVal, secondVal];
			console.log(pickerValue.value, "pickerValue.value");
		}
	}

	const confirm = () => {
		let monthStr = padZeroStr(month.value)
		let dayStr = padZeroStr(day.value)
		let hourStr = padZeroStr(hour.value)
		let minuteStr = padZeroStr(minute.value)
		let secondStr = padZeroStr(second.value)
		timeValue.value = `${year.value}-${monthStr}-${dayStr} ${hourStr}:${minuteStr}:${secondStr}`;
		emits('confirmPickDate', timeValue.value);
		close()

	}

	// 将时间分割成数组
	const convertDateString = (dateString) => {
		// 此处简化处理,实际应根据dateString格式进行解析
		let parts = dateString.split(/[- :]/);
		return [
			parseInt(parts[0], 10), // 年份
			parseInt(parts[1], 10) - 1, // 月份减1以适配数组索引
			parseInt(parts[2], 10) - 1, // 日减1以适配数组索引
			parseInt(parts[3], 10), // 小时
			parseInt(parts[4], 10), // 分
			parseInt(parts[5], 10) // 秒
		];
	}

	defineExpose({
		open,
		confirm
	})
</script>

<style lang="scss" scoped>
	.date-time {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100vh;
		z-index: 99999;

		.mask {
			position: absolute;
			top: 0;
			background: rgba(0, 0, 0, 0.5);
			width: 100%;
			height: 100vh;
		}

		.box {
			position: absolute;
			width: 100%;
			bottom: 0;
			background-color: #fff;
			border-radius: 20rpx 20rpx 0 0;
			overflow: hidden;
			height: 600rpx;

			.header {
				height: 88rpx;
				padding: 0 30rpx;
				border-bottom: 1rpx solid #e5e5e5;
				display: flex;
				align-items: center;
				justify-content: space-between;

				.determine {
					color: #333333;
					font-size: 32rpx;
					font-family: PingFang SC, PingFang SC-Regular;
					font-weight: 400;
				}
			}

			.picker-view {
				width: 100%;
				height: 400rpx;
			}

			.item {
				height: 100rpx;
				line-height: 100rpx;
				align-items: center;
				justify-content: center;
				text-align: center;
				font-size: 32rpx;
				font-family: PingFang SC-Regular, PingFang SC;
				font-weight: 400;
				color: #333333;
			}
		}
	}
</style>
相关推荐
别拿曾经看以后~42 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍