uni——月份选择(横向滑动tab,横向滚动选择日期)vue2、vue3

文章介绍了如何在uni-app应用中使用scroll-view组件实现动态加载年月按钮,展示了一个从特定范围到当前日期的月份列表切换和滚动功能的案例。
该文章已生成可运行项目,

一、案例展示

在这里插入图片描述

案例代码

已封装成组件使用
<template>
	<view>
		<view class="tabBox">
			<scroll-view scroll-x="true" :scroll-left="scrollLeft" :scroll-with-animation="true">
				<view class="box">
					<view class="tabItem" v-for="(item,index) in monthList" :key="index"
						:class="{'ac':tabCurrent == index}" @click="tabChange(index)">
						{{item.month}}
					</view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				itemWidth: 0, //每个item的宽度
				scrollLeft: 0, //滑动距离
				tabCurrent: 0, //默认当前月份
				sendMonth:'',
				monthList: [{
					id: 1,
					month: '1月'
				}, {
					id: 2,
					month: '2月'
				}, {
					id: 3,
					month: '3月'
				}, {
					id: 4,
					month: '4月'
				}, {
					id: 5,
					month: '5月'
				}, {
					id: 6,
					month: '6月'
				}, {
					id: 7,
					month: '7月'
				}, {
					id: 8,
					month: '8月'
				}, {
					id: 9,
					month: '9月'
				}, {
					id: 10,
					month: '10月'
				}, {
					id: 11,
					month: '11月'
				}, {
					id: 12,
					month: '12月'
				}]
			}
		},
		mounted() {
			// 先获取当前时间的月份
			let date = new Date();
			this.tabCurrent = date.getMonth(); // getMonth()返回的月份从0开始  正好符合tabCurrent  不用再加1了
			this.sendMonth = date.getMonth()+1; // 初次加载,传当前月份

			this.$nextTick(() => {
				const query = uni.createSelectorQuery().in(this);
				query.select('.tabItem').boundingClientRect(data => {
					// item宽度 = 自身宽度 + 8px右边距
					this.itemWidth = data.width + 8;
					this.scrollLeft = this.itemWidth * (this.tabCurrent - 1);
				}).exec();
			})
		},
		methods: {
			// 点击tab切换高亮,并进行滑动,(index-1)是为了点击项显示在第二栏的位置
			tabChange(index) {
				this.tabCurrent = index;
				// 传参的月份
				this.sendMonth = this.monthList[index].id
				this.scrollLeft = this.itemWidth * (index - 1);
				console.log(this.scrollLeft);
				this.$emit('tabChange',this.sendMonth)
			},
		}
	}
</script>
<style lang="scss">
	.tabBox {
		background: #ffffff;

		/* 隐藏滚动条样式 */
		::-webkit-scrollbar {
			width: 0;
			height: 0;
		}

		.box {
			width: 1400rpx;
			margin: 0 24rpx;
			display: flex;
			align-items: center;
			height: 90rpx;

			.tabItem {
				flex-shrink: 0;
				text-align: center;
				width: 100rpx;
				height: 60rpx;
				line-height: 60rpx;
				color: #636363;
				font-size: 28rpx;
				margin-right: 8px;
				border-radius: 50rpx;
			}

			.ac {
				background: #F9682A;
				font-size: 28rpx;
				color: #FFFFFF;
			}
		}
	}
</style>

参考网址

https://uniapp.dcloud.net.cn/component/scroll-view.html

2.年月按钮,从某个范围开始到当前的所有的月份。

案例展示

在这里插入图片描述

<template>
	<view>
		<view class="tabBox">
			<scroll-view scroll-x="true" :scroll-left="scrollLeft" :scroll-with-animation="true" class="scrollBox">
				<view class="box">
					<view class="tabItem" v-for="(item,index) in monthList" :key="index"
						:class="{'ac':tabCurrent == index}" @click="tabChange(item,index)">
						{{item}}
					</view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				itemWidth: 0, //每个item的宽度
				scrollLeft: 0, //滑动距离
				tabCurrent: 0, //默认当前月份
				sendMonth: '',
				monthList: [{}]
			}
		},
		mounted() {
			let date = new Date();
			let year = date.getFullYear();
			let month = date.getMonth() + 1;
			let day = date.getDate();
			let currentDate = `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`;
			this.getMonthsInRange('2020-01-01', currentDate);

			this.$nextTick(() => {
				const query = uni.createSelectorQuery().in(this);
				query.select('.tabItem').boundingClientRect(data => {
					this.itemWidth = data.width;
					this.scrollLeft = this.itemWidth * (this.tabCurrent - 1);
				}).exec();
			})
		},
		methods: {
			tabChange(item, index) {
				this.tabCurrent = index;
				this.sendMonth = item
				this.scrollLeft = this.itemWidth * (index - 1);
				this.$emit('tabChange', this.sendMonth)
			},
			getMonthsInRange(start, end) {
				var startMonth = new Date(start).getMonth();
				var endMonth = new Date(end).getMonth();
				var startYear = new Date(start).getFullYear();
				var endYear = new Date(end).getFullYear();
				var months = [];

				for (var i = startYear; i <= endYear; i++) {
					var monthStart = i === startYear ? startMonth : 0;
					var monthEnd = i === endYear ? endMonth : 11;

					for (var j = monthStart; j <= monthEnd; j++) {
						var month = j + 1;
						months.push(i + '-' + (month < 10 ? '0' + month : month));
					}
				}
				this.monthList = months
				this.tabCurrent = this.monthList.length - 1 // 初次加载默认显示
			}
		}
	}
</script>
<style lang="scss">
	.tabBox {
		background: #ffffff;

		.scrollBox {
			margin: 0 24rpx;
			width: 700rpx;
		}

		/* 隐藏滚动条样式 */
		::-webkit-scrollbar {
			width: 0;
			height: 0;
		}

		.box {
			// width: 1400rpx;
			display: flex;
			align-items: center;
			height: 90rpx;

			.tabItem {
				flex-shrink: 0;
				text-align: center;
				width: 140rpx;
				height: 60rpx;
				line-height: 60rpx;
				color: #636363;
				font-size: 28rpx;
				border-radius: 50rpx;
			}

			.ac {
				background: #F9682A;
				font-size: 28rpx;
				color: #FFFFFF;
			}
		}
	}
</style>

二、案例展示

在这里插入图片描述

<template>
	<layout title="安装订单" :left-arrow="true" back-height="0" bgColor="#ffffff" titleColor="#000000">
		<view class="tabBox">
			<scroll-view scroll-x="true" :scroll-left="scrollLeft" :scroll-with-animation="true">
				<view class="box">
					<view class="tabItem" v-for="(item,index) in tabList" :key="index"
						:class="{'ac':tabCurrent == item.id}" @click="tabChange(item,index)">
						{{item.name}}
					</view>
				</view>
			</scroll-view>
		</view>
	</layout>
</template>

<script setup>
	import {
		ref,
		reactive
	} from 'vue'
	import {
		onLoad,
		onReachBottom,
		onReady
	} from '@dcloudio/uni-app'
	import api from '@/request/api';
	import i from '@/libs/common/index.js'
	onLoad(() => {})
	onReachBottom(() => {
		console.log("触底");
	})
	onReady(() => {
		const query = uni.createSelectorQuery().in(this);
		query.select('.tabItem').boundingClientRect(data => {
			console.log(data);
			itemWidth.value = data.width + 8;
			scrollLeft.value = itemWidth.value * (tabCurrent.value - 1);
		}).exec();
	})
	const tabList = ref([{
		id: 1,
		name: '总站分配'
	}, {
		id: 2,
		name: '分站分配'
	}, {
		id: 3,
		name: '待接单'
	}, {
		id: 4,
		name: '进行中'
	}, {
		id: 5,
		name: '待验收'
	}, {
		id: 6,
		name: '已完成'
	}])
	const tabCurrent = ref(1) //默认
	const itemWidth = ref(0) //每个item的宽度
	const scrollLeft = ref(0) //滑动距离
	function tabChange(item,index) {
		tabCurrent.value = item.id
		scrollLeft.value = itemWidth.value * (index - 1);
	}
</script>


<style lang="scss">
	.tabBox {
		background: #ffffff;

		/* 隐藏滚动条样式 */
		::-webkit-scrollbar {
			width: 0;
			height: 0;
		}

		.box {
			width: 900rpx;
			border: 1px solid red;
			margin: 0 24rpx;
			display: flex;
			align-items: center;
			height: 100rpx;

			.tabItem {
				flex-shrink: 0;
				display: inline-block;
				padding: 14rpx 20rpx;
				color: #636363;
				font-size: 28rpx;
				margin-right: 8px;
				border-radius: 50rpx;
			}

			.ac {
				background: #0D4CB6;
				font-size: 28rpx;
				color: #FFFFFF;
			}
		}
	}
</style>

三、案例展示 vue3

在这里插入图片描述
在这里插入图片描述

<template>
	<view>
		<view class="head">
			<view class="box">
				<fui-nav-bar title="收入流水" background="#00000000" color="#FFFFFF">
					<fui-icon name="arrowleft" color="#ffffff" @click="i.back()"></fui-icon>
				</fui-nav-bar>
				<scroll-view scroll-x="true">
					<view class="items">
						<view class="items-item" v-for="(item,index) in tab" :key="index">
							<view class="item" :class="index==2?'active' : ''" @click="changTab(index)">
								{{item.value}}
							</view>
						</view>
					</view>
				</scroll-view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		reactive
	} from 'vue'
	import {
		onLoad,
		onShow
	} from '@dcloudio/uni-app'
	import i from '@/libs/common/index.js'
	import {
		userStore
	} from '@/store/userStore.js'
	import {
		commonStore
	} from '@/store/commonStore.js'
	const user = userStore()
	const common = commonStore()
	const tab = ref([])
	const month = ref([])

	onLoad(() => {
		tab.value = getMonthsRange()
		month.vlaue = tab.value[2].value
	})
	const getMonthsRange = (dateStr = '') => {
		let now = new Date();
		if (dateStr) {
			const [year, month] = dateStr.split("-").map(Number);
			now = new Date(year, month - 1, 1); // JS 月份从 0 开始
		}

		const months = [];
		for (let i = -2; i <= 2; i++) {
			const date = new Date(now.getFullYear(), now.getMonth() + i, 1);
			let month = date.getMonth() + 1
			if (month < 10) {
				month = '0' + month
			}
			months.push({
				value: date.getFullYear() + '-' + month,
			});
		}
		return months;
	}
	const changTab = (index) => {
		tab.value = getMonthsRange(tab.value[index].value)
		month.value = tab.value[2].value
	}
	
</script>

<style lang="scss">

	.head {
		width: 100%;
		height: 537rpx;
		position: relative;
		.box {
			position: absolute;
			width: 100%;
			height: 100%;
			z-index: 2;
			top: 0;
			left: 0;
		
			.items {
				display: flex;
				align-items: center;
				justify-content: space-around;
				// border-bottom: 1rpx solid rgba($color: #FFFFFF, $alpha: 0.18);
				padding-bottom: 10rpx;
				padding-top: 10rpx;
				.items-item {
					width: 20%;
					text-align: center;

					.active {
						margin: 0 auto;
						width: 140rpx;
						height: 60rpx;
						background: #FFFFFF;
						border-radius: 31rpx;
						line-height: 61rpx;
						text-align: center;
						color: #10664D !important;
					}

					.item {
						font-size: 28rpx;
						font-family: PingFang SC;
						font-weight: bold;
						color: #FFFFFF;
					}
				}

			}
		}
	}
</style>
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值