uniapp中英文格式日期选择器组件封装

uniapp中英文格式日期选择器(picker-view滚动选择器)

组件

<template>
	<uni-popup ref="popupDatePickers" type="center" class="datePickers common-popup" @change="change">
		<view class="content">
			<view class="head uni-align-justify">
				<view class="left" @click="change({ show: false })">{{ lang.cancel }}</view>
				<view class="right" @click="determine">{{ lang.Determine }}</view>
			</view>
			 
			<view class="picker">
				<!-- 年、月、/ 使用定位居中 -->
				<text class="text text-1">{{ cn ? "年" : "/" }}</text>
				<text class="text text-2">{{ cn ? "月" : "/" }}</text>
				<text class="text text-3" v-if="cn">日</text>
				<picker-view v-if="visible" :indicator-style="indicatorStyle" :value="pickerViewValue" @change="bindChange" class="picker-view">
						<picker-view-column v-if="cn">
							<view class="item" v-for="(item, index) in years" :key="`year${ String(index) }`">{{item}}</view>
						</picker-view-column>
						<picker-view-column v-else>
							<view class="item" v-for="(item, index) in days" :key="`days${ String(index) }`">{{item}}</view>
						</picker-view-column>
						<picker-view-column>
							<view class="item" v-for="(item, index) in months" :key="`month${ String(index) }`">{{item}}</view>
						</picker-view-column>
						<picker-view-column v-if="cn">
							<view class="item" v-for="(item, index) in days" :key="`days${ String(index) }`">{{item}}</view>
						</picker-view-column>
						<picker-view-column v-else>
							<view class="item" v-for="(item, index) in years" :key="`year${ String(index) }`">{{item}}</view>
						</picker-view-column>
				</picker-view>
			</view>
		</view>
	</uni-popup>
</template>

<script setup lang="ts">
	import { ref, watch, computed } from "vue";
	import store from "@/store";
	
	const array: any = [];
	
	let visible = ref(true);
	let indicatorStyle = ref(`height: 50px;`);
	const cn = computed(() => {
		return store.state.language === "cn";
	});
	
	let pickerViewValue = ref(cn.value ? [999, 0, 0] : [0, 0, 999]);
	
	let years = ref(array);
	let months = ref(array);
	let days = ref(array);
	let year = 0;
	let month = 0;
	let day = 0;
	let currentDate: number[] = [];
	
	const popupDatePickers = ref();
	
	const props = defineProps({
		show: {
			type: Boolean,
			default: false
		},
		date: {
			type: String,
			default: ""
		},
		// 开始年份
		start: {
			type: Number,
			default: 2020
		}
	});
	
	const $emit = defineEmits(["update:show", "determineFun"]);
	
	const setNum = (val: any) => {
		return val < 10 ? `0${ val }` : val;
	};
	
	watch(() => props.show, val => {
		if (val) {
			setData();
			popupDatePickers.value.open();
		} else {
			popupDatePickers.value.close();
		}
	});
	
	function change(e: any) {
		$emit("update:show", e.show);
	}
	
	// 设置列的数据
	function bindChange (e: any) {
		let a;
		let y;
		let val = e.detail.value;
		pickerViewValue.value = e.detail.value;
		y = years.value[val[cn.value ? 0 : 2]];
		a = months.value[val[1]];
		day = days.value[val[cn.value ? 2 : 0]];
		month = a;
		year = y;
		days.value = [];
		months.value = [];
		if (a || y) {			
			// 是否当前年,需要处理月份不能大于当前月
			if (year === currentDate[0]) {
				for (let i = 1; i <= 12; i++) {
					months.value.push(setNum(i));
					if (i === currentDate[1]) {
						break;
					}
				}
				let mLength = months.value.length - 1;
				if (pickerViewValue.value[1] > mLength) pickerViewValue.value[1] = mLength;
			} else {
				for (let i = 1; i <= 12; i++) {
					months.value.push(setNum(i));
				}
			}
			let currentTime: boolean = year === currentDate[0] && months.value[pickerViewValue.value[1]] === currentDate[1]; // 是否当前年、月
			if (a == 1 || a == 3 || a == 5 || a == 7 || a == 8 || a == 10 || a == 12) {
				for (let i = 1; i <= 31; i++) {
					days.value.push(setNum(i));
					if (currentTime && i === currentDate[2]) break; // 不能有大于当前日期的日期
				}
			} else if (a == 4 || a == 6 || a == 11 || a == 9) {
				for (let i = 1; i <= 30; i++) {
					days.value.push(setNum(i));
					if (currentTime && i === currentDate[2]) break;
				}
				
			} else if (a == 2) {
				if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
					for (let i = 1; i <= 29; i++) {
						days.value.push(setNum(i));
						if (currentTime && i === currentDate[2]) break;
					}
				} else {
					for (let i = 1; i <= 28; i++) {
						days.value.push(setNum(i));
						if (currentTime && i === currentDate[2]) break;
					}
				}
			}
			let dLength = days.value.length - 1;
			if (pickerViewValue.value[cn.value ? 2 : 0] > dLength) pickerViewValue.value[cn.value ? 2 : 0] = dLength;
		}
	}
	
	function setData() {
		if (years.value.length) return;
		const date = new Date();
		years.value = [];
		year = date.getFullYear();
		months.value = [];
		month = date.getMonth() + 1;
		days.value = [];
		day = date.getDate();
		currentDate = [year, month, day];
		for (let i = props.start; i <= year; i++) {
			years.value.push(i);
		}
		for (let i = 1; i <= 12; i++) {
			if (i === month) pickerViewValue.value[1] = i - 1; // 月索引
			months.value.push(setNum(i));
		}
		for (let i = 1; i <= 31; i++) {
			if (i === day) pickerViewValue.value[cn.value ? 2 : 0] = i - 1; // 日期索引
			days.value.push(setNum(i));
		}
	}
	
	function determine() {
		$emit("determineFun", {
			year: years.value[pickerViewValue.value[cn.value ? 0 : 2]],
			month: Number(months.value[pickerViewValue.value[1]]),
			day: Number(days.value[pickerViewValue.value[cn.value ? 2 : 0]])
		}); // 暴露事件及参数
		change({ show: false }); // 关闭弹窗
	}
	

</script>

<style lang="scss" scoped>
	@import "@/static/css/datePickers.scss";
</style>

datePickers.scss

.datePickers {
	font-weight: 400;
	:deep(.uni-popup__wrapper) {
		width: 100%;
		padding: 0 16px;
		.content {
			height: 310px;
			border-radius: 6px;
			background: #FFF;
			.head {
				font-size: 16px;
				padding: 18px 22px;
				border-bottom: 1px solid #f8f8f8;
				.left {
					color: #83868E;
				}
				.right {
					color: $main-color;
				}
			}
			.picker {
				padding: 0 14px;
				height: calc(100% - 60px);
				position: relative;
				.text {
					position: absolute;
					top: 50%;
					font-size: 12px;
					color: #181818;
				}
				.text-1 {
					left: 33.33%;
					transform: translate(-14px, -50%);
				}
				.text-2 {
					left: 66.66%;
					transform: translate(-22px, -50%);
				}
				.text-3 {
					left: 100%;
					transform: translate(-32px, -50%);
				}
				.picker-view {
					height: 100%;
					color: #181818;
					.item {
						line-height: 50px;
						text-align: center;
					}
				}
			}

		}
	}
}

使用

<template>
	<datePickers v-model:show="show" ref="DatePickersCom" @determineFun="determineFun"/>
</template>
<script lang="ts" setup>
	import { ref, computed, onMounted } from "vue";
	import datePickers from "@/components/datePickers.vue";
	let show = ref(false);
	const DatePickersCom = ref();
	interface dateObj {
		year: number;
		month: number;
		day: number;
	}

	// 确定数据
	function determineFun(data: dateObj) {
		console.log("确定数据: ", data);
		year.value = data.year;
		month.value = data.month;
		day.value = data.day;
	}
</script>

输出

输出

中文样式

中文样式

英文样式

英文样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值