uniapp多条件筛选

1.ScreenPopup筛选组件 

<template>
	<view class="screen-wrap">
		<view class="screen-select">
			<view class="s-item" v-for="(item,index) in menuList" :key="index" @tap="tapCurrentItem(item,index)">
				<text class="s-title">{{cTitle[index]|| item.title}}</text>
				<u-icon name="arrow-down-fill" size="10" />
			</view>
		</view>
		<u-popup :show="show" :round="26">
			<view class="screen-popup">
				<view class="close-icon" @tap="show=false">
					<u-icon name="close" color="#3D3D3D" size="22"></u-icon>
				</view>
				<view class="p-title">{{currentSelect.title }}</view>
				<view class="p-content border-top">
					<!-- 年份 -->
					<template v-if="currentSelect.type=='year'">
						<view class="tab-title">
							<u-icon name="play-left-fill" size="10" @click="updateIndex('minus')"
								:color="yearIndex == 0 ? '#9D9D9D' : ''" />
							<text>{{years[yearIndex][0]}}-{{years[yearIndex][years.length-1]}}</text>
							<u-icon name="play-right-fill" size="10" @click="updateIndex('plus')"
								:color="yearIndex == years.length-1 ? '#9D9D9D' : ''" />
						</view>
						<view class="year-grid">
							<view class="tab-item" v-for="y in years[yearIndex]" :key="y"
								:class="{ active: query[currentSelect.key] == y }" @tap="tabItem(currentSelect,y)">
								{{y}}
							</view>
						</view>
					</template>
					<!-- 输入框 -->
					<input v-model="query[currentSelect.key]" v-if="currentSelect.type=='input'"
						:placeholder="`请输入${currentSelect.title}`" class="mt-30" />
					<!-- 单选列表 -->
					<text v-if="child.label" v-for="(child,index) in currentSelect.tab" :key="index" class="tab-item"
						:class="{ active: query[currentSelect.key] === child.value }" @tap="tabItem(currentSelect,child)">
						{{ child.label}}
					</text>
				</view>
			</view>
			<view class="footer-btn space-between">
				<button class="btn mr-30" @tap="reset">重置</button>
				<button class="btn btn-primary" @tap="confirmBtn">确认</button>
			</view>
		</u-popup>
	</view>
</template>

<script>
	export default {
		name: "ScreenPopup",
		props: {
			// 循环筛选项
			menuList: {
				type: Array,
				default: () => []
			},
			// 筛选默认值
			defaultValue: {
				type: Object,
				default: () => {}
			}
		},
		data() {
			const date = new Date()
			let years = []
			const year = date.getFullYear()
			for (let i = 2020; i <= year + 19; i++) {
				years.push(i)
			}

			function spArr(arr, num) { //arr是你要分割的数组,num是以几个为一组
				let newArr = [] //首先创建一个新的空数组。用来存放分割好的数组
				for (let i = 0; i < arr.length;) { //注意:这里与for循环不太一样的是,没有i++
					newArr.push(arr.slice(i, i += num));
				}
				return newArr
			}
			years = spArr(years, 12)
			const yearIndex = years.findIndex(yy => yy.includes(year))

			return {
				// 筛选弹窗显示
				show: false,
				// 年份二维数组,一次显示12个
				years,
				// 当前年份
				year,
				// 当前年份所在的数组索引
				yearIndex,
				// 当前点击的select保存对应的item数据
				currentSelect: {},
				// 点击后显示的标题
				cTitle: [],
				// 点击select存储当前index
				cIndex: 0,
				// 选择的参数
				query: {},
			};
		},
		created() {
			this.copyQuery = JSON.parse(JSON.stringify(this.$props.defaultValue))
			this.query = this.$props.defaultValue
		},
		methods: {
			updateIndex(type) {
				if (type == 'plus') {
					this.years.length - 1 > this.yearIndex && this.yearIndex++
				} else {
					this.yearIndex != 0 && this.yearIndex--
				}
			},
			tapCurrentItem(item, index) {
				this.currentSelect = item
				this.cIndex = index
				this.show = true
			},
			isTabActive(item, child) {
				return this.query[item.key] === child.value;
			},
			// 点击小项事件
			tabItem(item, child) {
				if (this.isTabActive(item, child)) {
					// 如果已经选中,则取消选中
					this.$set(this.query, item.key, '')
					// 清空标题
					this.$set(this.cTitle, this.cIndex, '')
				} else {
					// 更新提交数据
					this.$set(this.query, item.key, typeof child == 'number' ? child : child.value)
					// 选择后改变标题
					this.$set(this.cTitle, this.cIndex, typeof child == 'number' ? child : child.label)
				}
			},
			// 筛选确认按钮
			confirmBtn() {
				this.$emit('confirm', this.query)
				this.show = false
			},
			// 重置
			reset() {
				// 重置所有选项
				// this.query = this.copyQuery
				// 重置打开项对应
				this.$set(this.query, this.currentSelect.key, this.copyQuery[this.currentSelect.key])
				if (this.currentSelect.type == 'year') {
					this.yearIndex = 0
				}
				this.$set(this.cTitle, this.cIndex, '')
				// 搜索
				this.confirmBtn()
			}
		}
	}
</script>

<style scoped lang="scss">
	.screen-wrap {
		.screen-select {
			display: flex;
			width: 100vw;
			padding: 30rpx 0;

			.s-item {
				width: 150rpx;
				display: flex;
				margin-left: 30rpx;

				.s-title {
					margin-right: 8rpx;
				}
			}
		}

		// 弹窗
		.screen-popup {
			position: relative;
			padding: 40rpx 30rpx 60rpx;

			.close-icon {
				position: absolute;
				right: 40rpx;
			}

			// 标题
			.p-title {
				font-size: 34rpx;
				text-align: center;
				padding-bottom: 40rpx;
			}

			// 小项内容区
			.p-content {
				padding-bottom: 200rpx;
				max-height: 50vh;
				overflow: auto;

				.tab-title {
					display: flex;
					justify-content: center;
					margin: 30rpx 0;

					text {
						margin: 0 16rpx;
					}
				}

				// 年份
				.year-grid {
					display: grid;
					grid-template-columns: repeat(3, 3fr);
					gap: 18rpx;
				}

				// 小项
				.tab-item {
					width: 100%;
					display: inline-block;
					box-sizing: border-box;
					text-align: center;
					padding: 20rpx;
					margin: 20rpx 18rpx 0 0;
					font-size: 26rpx;
					background-color: #F6F6F6;
					border: 1rpx solid #F6F6F6;
					border-radius: 43rpx;

					// 选中样式
					&.active {
						color: #DB4B40;
						background: rgba(219, 75, 64, 0.1);
					}
				}
			}
		}

		.footer-btn button {
			border-radius: 60rpx;
		}
	}
</style>

2.页面中使用

<template>
	<!-- 筛选组件 -->
  <ScreenPopup ref="screen" :defaultValue="query" @confirm="screenConfirm" :menuList="menuList" />
</template>

<script>
  data() {
	return {
     query: {
		year:2024,
		storeQry: ''
	  },
	menuList: [
		{ key: 'year', title: '工作年份', type: 'year' },
		{
		key: 'storeQry',
		title: '接收状态',
		tab: [{ label: '全部', value: '' }, { label: '采煤一区', value: 1 },{ label: '采煤2区', value: 2 }]
		}]
	 }
  },
  methods: {
  // 筛选确认
  screenConfirm(data) {
  this.query = data
  this.init('query')
 }
}
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值