Bootstrap

uniapp下拉菜单

一、示例图

1.状态为多选,选中后显示已选择的数量 ,如下图:

2.排序为单选,显示当前选中的名称,如下图:

二、状态、排序相关代码 

部分代码使用了的uView组件Icon 图标 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架

<template>
	<view class="wrapper">
		<view class="wrapper-tap">
			<!-- 状态 -->
			<view class="tap" @click="handlescreen('state')">
				<span :class="(isShowState || this.selectStateArr.length >0)? 'yes-title':'no-title'">状态
					<span v-if="this.selectStateArr.length >0" class="sumStyle">{
  
  {this.selectStateArr.length}}</span>
				</span>
				<view v-if="isShowState == false"
					:class="this.selectStateArr.length >0 ? 'triangle-show-1' :'triangle-show'"></view>
				<view v-if="isShowState == true" class="triangle"></view>
			</view>
			<!-- 排序 -->
			<view class="tap" @click="handlescreen('sort')">
				<span v-if="sortValue == ''" :class="isShowSort ? 'yes-title':'no-title'">排序</span>
				<span v-else class="sortNameStyle">{
  
  {sortName}}</span>
				<view v-if="isShowSort == false" :class="sortName !='' ? 'triangle-show-1' :'triangle-show'"></view>
				<view v-if="isShowSort == true" class="triangle"></view>
			</view>
		</view>

		<!-- 状态遮罩层 -->
		<view :class="isShowState?'make':''" @touchmove.stop.prevent="disabledScroll" @click="isShowState = false">
		</view>
		<!-- 状态弹窗 -->
		<view class="popup-box" :class="isShowState?'popup-transition-status':'popup-none'">
			<view class="status-box">
				<scroll-view class="stateStyle" scroll-y="true">
					<view v-for="(item,index) in stateList" :key="index">
						<u-cell-group>
							<u-cell @click="selectStateClick(item,index)">
								<view slot="title" style="padding: 0 5px;font-size:14px"
									:class="selectStateArr.indexOf(item.id) != -1 ?'yes-title':'no-title'">
									{
  
  {item.name}}
								</view>
								<view slot="value" v-if="selectStateArr.indexOf(item.id) != -1">
									<u-icon name="checkmark" size="18" color="#287FE0"></u-icon>
								</view>
							</u-cell>
						</u-cell-group>
					</view>
				</scroll-view>
			</view>
			<view class="screen-btn">
				<view class="screen-reset" @click="handleReset">
					清空
				</view>
				<view class="screen-view" @click="handleViewCode">
					搜索
				</view>
			</view>
		</view>
		<!-- 排序遮罩层 -->
		<view :class="isShowSort?'make':''" @touchmove.stop.prevent="disabledScroll" @click="isShowSort = false">
		</view>
		<!-- 排序弹窗 -->
		<view class="popup-box" :class="isShowSort ? 'popup-transition-sort':'popup-none'">
			<view class="sort-box">
				<scroll-view class="stateStyle" scroll-y="true">
					<view v-for="(item,index) in sortList" :key="index">
						<u-cell-group>
							<u-cell @click="selectSortClick(item,index)">
								<view slot="title" style="padding: 0 5px;font-size:14px"
									:class="indexSort == index ?'yes-title':'no-title'">
									{
  
  {item.name}}
								</view>
								<view slot="value" v-if="indexSort == index">
									<u-icon name="checkmark" size="18" color="#287FE0"></u-icon>
								</view>
							</u-cell>
						</u-cell-group>
					</view>
				</scroll-view>
			</view>
			<view class="screen-btn">
				<view class="screen-reset" @click="handleReset">
					清空
				</view>
				<view class="screen-view" @click="handleViewCode">
					搜索
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				// 状态弹框是否展示
				isShowState: false,
				// 状态 - 默认选中数据
				selectStateArr: ['1', '2'],
				//状态数组
				stateList: [{
					name: "暂存",
					id: '1'
				}, {
					name: "已提交",
					id: '2'
				}, {
					name: "进行中",
					id: '3'
				}, {
					name: "已审批",
					id: '4'
				}, {
					name: "驳回",
					id: '5'
				}],
				// 排序弹框是否显示
				isShowSort: false,
				//排序默认不选中
				indexSort: -1,
				//排序选中val
				sortValue: '',
				//排序选中名称
				sortName: '',
				//排序数组
				sortList: [{
					name: "aaaa",
					id: '1'
				}, {
					name: "bbbb",
					id: '2'
				}, {
					name: "时间正序",
					id: '3'
				}, {
					name: "时间倒序",
					id: '4'
				}, {
					name: "cccc",
					id: '5'
				}, {
					name: "eeee",
					id: '6'
				}]
			}
		},
		created() {},
		methods: {
			/**
			 * 状态 多选
			 */
			selectStateClick(item) {
				let indexItem = this.selectStateArr.indexOf(item.id);
				if (indexItem == -1) {
					this.selectStateArr.push(item.id);
				} else {
					this.selectStateArr.map((e, index) => {
						if (e == item.id) {
							this.selectStateArr.splice(index, 1);
						}
					})
				}
			},
			/** 
			 * 排序
			 */
			selectSortClick(item, index) {
				if (index != this.indexSort) {
					this.indexSort = index
					this.sortValue = item.id
					this.sortName = item.name
				} else {
					this.indexSort = -1
					this.sortValue = ''
					this.sortName = ''
				}
			},
			/** 
			 * 弹窗是否展开
			 */
			handlescreen(type) {
                if (type == 'state') {
					this.isShowState = !this.isShowState
					this.isShowSort = false
				} else if (type == 'sort') {
					this.isShowSort = !this.isShowSort
					this.isShowState = false
				}
			},
			/** 
			 * 搜索
			 */
			handleViewCode() {},
			/** 
			 * 清空 
			 */
			handleReset(type) {
				//-------------------恢复默认选中的状态-----------------------
				this.selectStateArr = ['1', '2']
				//-------------------清空已选排序-----------------------
				this.sortValue = ''
				this.sortName = ''
				this.indexSort = -1

				this.isShowState = false
				this.isShowSort = false
			},
			/** 
			 * 阻止滚动
			 */
			disabledScroll() {
				return
			}
		}
	}
</script>

<style lang="scss" scoped>
	.wrapper {
		width: 100%;
		position: relative;
		background: #fff;
	}

	.make {
		position: fixed;
		width: 100%;
		height: 100vh;
		background: #000000;
		opacity: 0.6;
		z-index: 9;
	}

	.wrapper-tap {
		border-bottom: 1px solid #f4f4f5;
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 750rpx;
		height: 72rpx;
		border-radius: 28rpx 28rpx 0rpx 0rpx;

		.tap {
			display: flex;
			align-items: center;
			justify-content: center;
			width: 50%;
			font-size: 28rpx;
			font-family: PingFangSC-Regular, PingFang SC;
			font-weight: 400;
			color: #333333;
		}
	}

	.popup-box {
		position: absolute;
		z-index: 999;
		width: 100%;
		height: 0rpx;
		background: #ffffff;
		border-radius: 0rpx 0rpx 28rpx 28rpx;
		overflow: hidden;
	}

	.popup-transition {
		height: 650rpx;
	}

	.popup-none {
		display: none;
	}

	//正三角
	.triangle {
		width: 0;
		height: 0;
		border-left: 5px solid transparent;
		border-right: 5px solid transparent;
		border-bottom: 5px solid #287fe0;
		margin-left: 10rpx;
	}

	//倒三角
	.triangle-show {
		width: 0;
		height: 0;
		border-left: 5px solid transparent;
		border-right: 5px solid transparent;
		border-top: 5px solid #D0D0D0;
	}

	//倒三角(选中有值时)
	.triangle-show-1 {
		width: 0;
		height: 0;
		border-left: 5px solid transparent;
		border-right: 5px solid transparent;
		border-top: 5px solid #287fe0;
	}


	// 展开动画
	@keyframes example {
		from {
			height: 0rpx;
		}

		to {
			height: 800rpx;
		}
	}

	// 筛选
	.screen-box {
		width: 100%;
		height: 500rpx;
		display: flex;
		justify-content: flex-start;
		border-radius: 0rpx 0rpx 28rpx 28rpx;

		.screen-province {
			width: 200rpx;
			height: 100%;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			background: #f4f4f5;
			border-right: 1px solid #f4f4f5;

			.item-province {
				width: 200rpx;
				height: 90rpx;
				background-color: #F4F4F5;
				display: flex;
				align-items: center;
				justify-content: center;
			}

			.active-item {
				color: #287fe0;
				border-width: 15rpx;
				background-color: #ffffff;
			}

			.active-item-city {
				color: #287fe0;
				background-color: #ffffff;
			}
		}

		.screen-province-right {
			width: calc(100vw -200rpx);

			.item-province {

				.item-name {
					box-sizing: border-box;
					width: 160rpx;
					height: 25px;
					color: #3D3F42;
					background: #F4F4F5;
					border-radius: 5px;
					margin: 8px 0px 0 5px;
					padding-top: 6px;
					font-size: 11px;
					text-align: center;
				}

				.selectColor {
					box-sizing: border-box;
					width: 160rpx;
					height: 25px;
					color: #287fe0;
					background: #F4F4F5;
					border-radius: 5px;
					margin: 8px 0px 0 5px;
					padding-top: 6px;
					font-size: 11px;
					text-align: center;
					border: 1px solid #287fe0,
				}
			}
		}
	}


	::v-deep .silder-right-bottom .uni-scroll-view-content {
		display: flex;
		flex-wrap: wrap;
		height: 110px;
	}

	::v-deep .silder-right-bottom1 .uni-scroll-view-content {
		display: flex;
		flex-wrap: wrap;
		height: 80px;
	}

	// 按钮
	.screen-btn {
		height: 150rpx;
		position: absolute;
		bottom: 12rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 32rpx 28rpx 0;
		box-sizing: border-box;

		.screen-reset {
			width: 235rpx;
			height: 68rpx;
			border-radius: 20rpx;
			font-size: 32rpx;
			font-family: PingFangSC-Medium, PingFang SC;
			font-weight: 500;
			background-color: #FD981A;
			color: #fff;
			text-align: center;
			line-height: 66rpx;
			margin-right: 10rpx;
		}

		.screen-view {
			width: 435rpx;
			height: 68rpx;
			background: #287fe0;
			border-radius: 20rpx;
			font-size: 32rpx;
			font-family: PingFangSC-Medium, PingFang SC;
			font-weight: 500;
			color: #FFFFFF;
			text-align: center;
			line-height: 66rpx;
			margin-left: 10rpx;
		}
	}


	.range-title {
		color: #c6c6c6;
		display: flex;
		justify-content: space-between;
		padding: 20px 10px 0px 10px;
	}

	.range-title-select {
		color: red;
		display: flex;
		justify-content: space-between;
		padding: 20px 10px 0px 10px;
	}

	.range-slider {
		padding-left: 5px;
	}

	.yes-title {
		color: #287fe0;
	}

	.no-title {
		color: #000000;
	}

	.sumStyle {
		font-size: 20rpx;
		color: #ffffff;
		border-radius: 50%;
		background-color: #287fe0;
		padding: 2rpx 10rpx;
	}

	.popup-transition-status {
		height: 480rpx;
	}

	.status-box {
		width: 100%;
		height: 340rpx;
		display: flex;
		justify-content: flex-start;
		border-radius: 0rpx 0rpx 28rpx 28rpx;
	}

	::v-deep .u-cell__body {
		padding: 7px 15px
	}

	::v-deep .u-line {
		transform: scaleY(0.2) !important;
	}

	.popup-transition-sort {
		height: 560rpx;
	}

	.sort-box {
		width: 100%;
		height: 420rpx;
		display: flex;
		justify-content: flex-start;
		border-radius: 0rpx 0rpx 28rpx 28rpx;
	}

	.sortNameStyle {
		color: #287fe0;
		width: calc((100vw - 50px) / 4);
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		text-align: right;
	}
</style>

ps:大家要是有更好的方法可以@我一下

;