横向日期选择器-uniapp

442 阅读1分钟

效果

image.png

代码

<template>
	<view class="headerDate-index">
		<view class="selectTab">
			<view @click="change('day')" :class="(selectItem === 'day') ? 'selected' : ''">本日</view>
			<view @click="change('mon')" :class="(selectItem === 'mon') ? 'selected' : ''">本月</view>
			<view @click="change('year')" :class="(selectItem === 'year') ? 'selected' : ''">本年</view>
			<view @click="change('sum')" :class="(selectItem === 'sum') ? 'selected' : ''">累计</view>
		</view>
		<view class="selectDate">
			<image @click="selectTime('next')" class="img" src="/static/images/select-left.png" mode="aspectFit"></image>
			<view class="showBox">
				<view ref="timeBox" class="timeBox">
					<view>{{previousTime}}</view>
					<view>{{selectTimeText}}</view>
					<view>{{nextTime}}</view>
				</view>
			</view>
			<image @click="selectTime('prev')" class="img" src="/static/images/select-right.png" mode="aspectFit"></image>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				selectItem: 'day', //选项设置,默认为日
				selectYear: new Date().getFullYear(),
				selectMon: new Date().getMonth() + 1,
				selectDay: new Date().getDate(),
				animTime:250,//动画执行时间(毫秒)
			}
		},
		computed:{
			selectTimeText:{
				get(){
					return this.formatTime(this.selectYear,this.selectMon,this.selectDay);
				},
				set(val){
					// 延迟展示修改时间
					setTimeout(()=>{
						var date = new Date(val);
						this.selectYear = date.getFullYear();
						this.selectMon = date.getMonth() + 1;
						this.selectDay = date.getDate();
					},this.animTime)
				}
			},
			previousTime(){
				return this.getNextDate(this.selectTimeText,-1)
			},
			nextTime(){
				return this.getNextDate(this.selectTimeText,1)
			},
		},
		methods: {
			change(select) {
				this.selectItem = select;
			},
			// 选择时间
			selectTime(dir){
				var anim;//动画样式
				var time;//选择的时间
				if(dir === 'prev'){
					// 上一个
					time = this.previousTime;
					anim = `prev ${this.animTime/1000}s 1 ease-out`;
				}else if(dir === 'next'){
					// 下一个
					time = this.nextTime;
					anim = `next ${this.animTime/1000}s 1 ease-out`;
				}
				this.selectTimeText = time;
				this.$refs.timeBox.$el.style.animation = anim;//动画样式在App.vue中
				// 清除动画样式
				setTimeout(()=>{
					this.$refs.timeBox.$el.style.animation = '';
				},this.animTime)
			},
			// 获取每个月的天数
			getMonthDays(year, month) {
				var thisDate = new Date(year, month, 0); //当天数为0 js自动处理为上一月的最后一天
				return thisDate.getDate();

			},
			// date 代表指定的日期,格式:2022/06-02
			// day 传-1表始前一天,传1表始后一天
			// JS获取指定日期的前一天,后一天
			getNextDate(date, day) { 
			  var dd = new Date(date);
			  dd.setDate(dd.getDate() + day);
			  return this.formatTime(dd.getFullYear(),dd.getMonth()+1,dd.getDate());
			},
			// 格式化时间-返回2022/04/11 格式时间
			formatTime(year,mon,day){
				var yearStr = year;
				var monStr = mon < 10 ? '0' + mon :mon ;
				var dayStr = day < 10 ? '0' + day :day ;
				return `${yearStr}/${monStr}/${dayStr}`;
			}
			
		},
	}
</script>


<style lang="less">
	@width:414rpx;//一个日期的宽度
	
	.headerDate-index {
		width: 750rpx;
		height: 276rpx;
		background: #FFFFFF;
		padding: 30rpx;
		box-sizing: border-box;
		
		.selectTab {
			margin-bottom: 45rpx;
			display: flex;
			height: 72rpx;
			justify-content: space-between;
			box-sizing: border-box;
			align-items: center;
			font-size: 26rpx;
			font-weight: 800;
			color: #D30000;
			border: 2rpx solid #D30000;
			border-radius: 20rpx;
			overflow: hidden;

			&>:nth-child(n) {
				height: 72rpx;
				line-height: 72rpx;
				text-align: center;
				flex: 1;
				border-right: 2rpx solid #D30000;
			}

			&>:last-child {
				border: none;
			}

			.selected {
				background-color: #D30000;
				color: white;
			}
		}

		.selectDate {
			display: flex;
			justify-content: space-between;
			font-size: 38rpx;
			font-weight: 800;
			color: #333333;
			padding: 0 80rpx;
			align-items: center;

			.img {
				width: 18rpx;
				height: 26rpx;
			}

			.showBox {
				width: @width;
				height: 50rpx;
				text-align: center;
				margin: 0 40rpx;
				position: relative;
				overflow: hidden;

				.timeBox {
					position: absolute;
					display: flex;
					left: -@width;
					&>:nth-child(n) {
						width: @width;
						height: 50rpx;
						text-align: center;
					}
					
				}
			}
		}
	}
</style>