uni-app 自定义组件周选择器

本文介绍了如何在uni-app中使用uni-popup和picker-view组件创建一个可交互的周选择器,包括数据绑定、监听和事件处理,以实现在不同年份下选择指定的周数。
摘要由CSDN通过智能技术生成

利用uni-popup,picker-view 实现周选择器

<template>
	<view>

		<uni-popup ref="popup" type="bottom" background-color="#fff">
			<view class="my_popup">
				<view class="my_selectDeta">
					<div class="my_button" @click="iconClose">
						取消
					</div>

					<div class="my_button" type="primary" @click="confirm">
						确定
					</div>

				</view>

				<picker-view :indicator-style="indicatorStyle" :value="selectValue" class="picker-view"
					@change="bindChange">
					<picker-view-column>
						<view v-for="(item, index) in this.years" :key="index" class="item">{{ item }}年</view>
					</picker-view-column>

					<picker-view-column v-show="!current">
						<view v-for="(item, index) in weeks" :key="index" class="item">{{ `第${index + 1}周(` + item + ')'
							}}</view>
					</picker-view-column>
				</picker-view>

			</view>
		</uni-popup>
	</view>
</template>


<script>

export default {
	data() {
		return {
			dateObj: {},
			current: false,
			indicatorStyle: `height: 20rpx;`,
			myDate: new Date(),
			years: [],
			year: null,
			months: [],
			month: null,
			week: '',
			showWeek: '第一周',
			payload: {},
			selectValue: [5, 0],
			cacheSelectValue: [5, 0]
		}
	},
	computed: {
		weeks() {
			const ONE_DAY = 24 * 3600 * 1000;
			let firstDay =
				new Date(this.year + '/01/01').getDay() == 0
					? 7
					: new Date(this.year + '/01/01').getDay();
			let weeklist = [];
			let firstweekday = '';
			let endweekday = new Date(this.year + '/12/28').getTime();
			if (firstDay > 4) {
				firstweekday =
					new Date(this.year + '/01/01').getTime() +
					(8 - firstDay) * ONE_DAY;
			} else if (firstDay <= 4) {
				firstweekday =
					new Date(this.year + '/01/01').getTime() -
					(firstDay - 1) * ONE_DAY;
			}
			for (let i = 0; i < 54; i++) {
				let numWeek = i * 7 * ONE_DAY;
				let firstday = firstweekday + numWeek;
				let endday = firstday + 6 * ONE_DAY;
				if (firstday <= endweekday) {

					weeklist.push(

						`${uni.$u.timeFormat(firstday, 'mm/dd')}-${uni.$u.timeFormat(endday, 'mm/dd')}`
					);
				}
			}
			return weeklist;
		},
	},
	watch: {
		year: {
			handler(newValue) {
				console.log(2222);
				const index = this.years.findIndex((item) => item == newValue);
				this.selectValue = [index, 0];
			},
			deep: true // 深度监听父组件传过来对象变化
		},
	},
	mounted() {
		this.init()
	},
	methods: {
		// 初始化时的默认当前周
		init(data = '') {
			for (let i = this.myDate.getFullYear() - 74; i <= this.myDate.getFullYear() + 26; i++) {
				this.years.push(i);
			}
			console.log(data);
			let beginTime = uni.$u.timeFormat(this.getWeek(0,data), 'mm/dd')
			let endTime = uni.$u.timeFormat(this.getWeek(1,data), 'mm/dd')
			console.log(beginTime, endTime);
			this.year = data ? new Date(data).getFullYear() :  this.myDate.getFullYear()
			this.week = `${beginTime}-${endTime}`
			this.selectValue = [this.years.indexOf(this.year), this.weeks.indexOf(this.week)]
			this.showweek = '第' + (this.selectValue[1] + 1) + '周';
			this.$nextTick(() => {
				this.selectValue = [this.years.indexOf(this.year), this.weeks.indexOf(this.week)]
				this.changeDateObj()
			})
		
			// this.$emit('changeWeekTime', this.dateObj)
		},
		bindChange(e) {
			console.log(e.detail.value);
			this.cacheSelectValue = e.detail.value
			this.year = this.years[this.cacheSelectValue[0]];
			// this.month = this.months[val[1]];
			this.week = this.weeks[this.cacheSelectValue[1]];
			this.showweek = '第' + (this.cacheSelectValue[1] + 1) + '周';

		},
		// 获取当前第几周
		getYearWeek(a, b, c) {
			var date1 = new Date(a, parseInt(b) - 1, c),
				date2 = new Date(a, 0, 1),
				d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
			return Math.ceil((d + (date2.getDay() + 1 - 1)) / 7);
		},

		// 获取当前周 
		getWeek(type,data="") {
			let now = new Date(data)
			let day = now.getDay() //返回星期几的某一天;
			if (!type) {
				let dayNumber = day == 0 ? 6 : day - 1
				now.setDate(now.getDate() - dayNumber)
			} else {
				let dayNumber = day == 0 ? 0 : 7 - day
				now.setDate(now.getDate() + dayNumber)
			}
			let date = now.getDate()
			let month = now.getMonth() + 1
			//年-月-日
			let s = now.getFullYear() + '-' + (month < 10 ? '0' + month : month) + '-' + (date < 10 ? '0' +
				date :
				date)

			let datebefore = now
			return datebefore
		},
		open() {
			console.log(this.selectValue);
			this.year = this.years[this.selectValue[0]];
			// this.month = this.months[val[1]];
			this.week = this.weeks[this.selectValue[1]];
			this.showweek = '第' + (this.selectValue[1] + 1) + '周';
			console.log(this.selectValue);
			this.$refs['popup'].open('bottom');
		},
		// 改变传参
		changeDateObj() {
			const [firstWeek, lastWeek] = this.week
				.split('-')
				.map((item) => item.replace('/', '-'));
			this.payload = {
				startTime: this.year + '-' + firstWeek,
				endTime: this.year + '-' + lastWeek,
				showTime: this.year + '-' + this.showweek
			};
			this.dateObj = this.payload;
			this.$emit('changeWeekTime', this.dateObj)
		},
		confirm() {
			this.changeDateObj()
			this.selectValue = this.cacheSelectValue
			this.$refs['popup'].close();
			
		},
		iconClose() {
			this.$refs['popup'].close();
			this.cacheSelectValue = [5, 0]
		},


	}
}
</script>

<style lang="scss">
.my_popup {
	height: 250rpx;
	border-radius: 8rpx 8rpx 0 0;
	position: relative;
	font-size: 15rpx;
	font-weight: 500;

	color: #1b1d21;

	.my_selectDeta {
		display: flex;
		justify-content: space-between;
		height: 40rpx;
		line-height: 40rpx;
		text-align: center;
		padding: 0 40rpx;
		color: rgb(96, 98, 102);
		border-bottom: 1px solid #f5f7f8;
	}

	.my_button {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 50rpx;
		margin: 5rpx;
	}

	.picker-view {
		width: 750rpx;
		height: 600rpx;
		margin-top: 10rpx;

		.item {
			line-height: 20rpx;
			text-align: center;
		}
	}

	.tabbar {
		box-sizing: border-box;
		width: 328rpx;
		padding: 8rpx;
		height: 72rpx;
		margin: 0 auto;
		display: flex;
		border-radius: 8rpx;
		background-color: #f4f5f7;
		justify-content: space-around;

		view {
			padding: 5rpx 12rpx;
			font-size: 30rpx;
			color: #1b1d21;
			background: #f4f5f7;
		}

		.bg {
			background: rgb(1, 1, 202);
			border-radius: 8rpx;
			color: white;
		}
	}
}

::v-deep .my_popup .picker-view {
	height: 250rpx;
}
</style>

实现效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值