uview下拉菜单Dropdown整合个性化下拉

该组件必须结合u-dorpdown和u-dropdown-item一起使用,展开的内容由u-dropdown-item通过传递参数或者slot提供

u-dropdown-item每个独立下拉菜单

组件的菜单栏标题由u-dropdown-item通过title参数提供
u-dropdown-item带有默认的单选展示功能,通过options(见下方说明)配置,传入slot则会覆盖默认功能,通过v-model双向绑定options选中项的value值

<template>
	<view class="container container21094">
		<view class="flex diygw-dropdown diygw-col-24">
			<u-dropdown class="flex-sub" direction="down" ref="refDropdowns">
				<u-dropdown-item @change="changeDropdowns0" v-model="dropdowns0" title="菜单一" :options="dropdownsDatas0"></u-dropdown-item>
				<u-dropdown-item @change="changeDropdowns1" v-model="dropdowns1" title="菜单二" :options="dropdownsDatas1"></u-dropdown-item>
			</u-dropdown>
		</view>
		<view class="clearfix"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				//用户全局信息
				userInfo: {},
				//页面传参
				globalOption: {},
				//自定义全局变量
				globalData: {},
				dropdowns0: '',
				dropdowns1: '',
				dropdownsDatas0: [
					{ text: '全部商品', value: '0' },
					{ text: '新款商品', value: '1' },
					{ text: '活动商品', value: '2' }
				],
				dropdownsDatas1: [
					{ text: '默认排序', value: '0' },
					{ text: '好评排序', value: '1' },
					{ text: '销量排序', value: '2' }
				]
			};
		},
		onShow() {
			this.setCurrentPage(this);
		},
		onLoad(option) {
			this.setCurrentPage(this);
			if (option) {
				this.setData({
					globalOption: this.getOption(option)
				});
			}

			this.init();
		},
		methods: {
			async init() {},
			closeDropdowns() {
				this.$refs.refDropdowns.close();
			},
			changeDropdowns0(evt) {
				let item = this.dropdownsDatas0.find((item) => {
					return item.value == evt;
				});
				item && item.action && this.navigateTo(item.action);
			},
			changeDropdowns1(evt) {
				let item = this.dropdownsDatas1.find((item) => {
					return item.value == evt;
				});
				item && item.action && this.navigateTo(item.action);
			}
		}
	};
</script>

<style lang="scss" scoped>
	.container21094 {
	}
</style>


配置选项卡默认功能


如上所示,u-dropdown-item具有默认的单选功能,这里主要讲解其options和v-model参数:

options参数为一个数组,元素为对象,其中label为需要展示的提示文字,value为点击时双向绑定给v-model的值,v-model初始化时如果设置 某个options中的value,则该条目将会被默认选中:

配置选项卡自定义功能


在选项卡默认的单选功能无法满足的时候,我们可以给u-dropw-item传递slot来自定义需要展示的内容。

价格区间下拉菜单的设计

户型下拉设计

生成源码效果

查看源码

<template>
	<view class="container container21094">
		<u-form :model="form" :rules="formRules" :errorType="['message', 'toast']" ref="formRef" class="flex diygw-form diygw-col-24">
			<view class="flex diygw-dropdown diygw-col-24">
				<u-dropdown class="flex-sub" direction="down" ref="refDropdowns">
					<u-dropdown-item title="价格">
						<view class="bg-white">
							<view class="flex flex-wrap diygw-col-24 flex-direction-column">
								<text class="diygw-col-24 text1-clz"> 价格区间(万) </text>
								<view class="flex diygw-col-24 items-center flex-nowrap flex1-clz">
									<u-form-item class="diygw-col-0 start-clz diygw-form-item-notpadding" labelPosition="top" prop="start">
										<u-input :focus="formData.startFocus" placeholder="请输入最低价格" v-model="form.start"></u-input>
									</u-form-item>
									<text class="diygw-col-0 text-clz"> 至 </text>
									<u-form-item class="diygw-col-0 end-clz diygw-form-item-notpadding" labelPosition="top" prop="end">
										<u-input :focus="formData.endFocus" placeholder="请输入最高价格" v-model="form.end"></u-input>
									</u-form-item>
								</view>
								<u-form-item labelWidth="auto" class="diygw-col-24 ucheckbox2-clz diygw-form-item-notpadding" labelPosition="top" prop="ucheckbox2">
									<diy-checkbox class="diygw-col-24" activeColor="#ff5c47" activeBgColor="#ffecee" mode="radio" v-model="form.ucheckbox2" :list="formData.ucheckbox2Datas" @change="changeFormUcheckbox2"> </diy-checkbox>
								</u-form-item>
								<view class="flex flex-wrap diygw-col-24 flex2-clz">
									<button @click="resetForm" class="diygw-col-8 btn-clz diygw-btn-default">重置</button>
									<button @click="submitForm" class="diygw-col-0 btn1-clz diygw-btn-default">确定</button>
								</view>
							</view>
							<view class="clearfix"></view>
						</view>
					</u-dropdown-item>
					<u-dropdown-item title="户型">
						<view class="bg-white">
							<view class="flex flex-wrap diygw-col-24 flex-direction-column">
								<u-form-item labelWidth="auto" class="diygw-col-24 ucheckbox-clz diygw-form-item-notpadding" label="居室" labelPosition="top" prop="ucheckbox">
									<diy-checkbox class="diygw-col-24" activeColor="#ff5c47" activeBgColor="#ffecee" mode="checkbox" v-model="form.ucheckbox" :list="formData.ucheckboxDatas" @change="changeFormUcheckbox"> </diy-checkbox>
								</u-form-item>
								<u-form-item labelWidth="auto" class="diygw-col-24 ucheckbox3-clz diygw-form-item-notpadding" label="居室" labelPosition="top" prop="ucheckbox3">
									<diy-checkbox class="diygw-col-24" activeColor="#ff5c47" activeBgColor="#ffecee" mode="checkbox" v-model="form.ucheckbox3" :list="formData.ucheckbox3Datas" @change="changeFormUcheckbox3"> </diy-checkbox>
								</u-form-item>
								<u-form-item labelWidth="auto" class="diygw-col-24 ucheckbox1-clz diygw-form-item-notpadding" label="卫生间" labelPosition="top" prop="ucheckbox1">
									<diy-checkbox class="diygw-col-24" activeColor="#ff5c47" activeBgColor="#ffecee" mode="checkbox" v-model="form.ucheckbox1" :list="formData.ucheckbox1Datas" @change="changeFormUcheckbox1"> </diy-checkbox>
								</u-form-item>
								<view class="flex flex-wrap diygw-col-24 flex3-clz">
									<button @click="resetForm" class="diygw-col-8 btn2-clz diygw-btn-default">重置</button>
									<button @click="submitForm" class="diygw-col-0 btn3-clz diygw-btn-default">确定</button>
								</view>
							</view>
							<view class="clearfix"></view>
						</view>
					</u-dropdown-item>
					<u-dropdown-item title="排序">
						<view class="bg-white">
							<view class="flex flex-wrap diygw-col-24 flex-direction-column">
								<u-form-item class="diygw-col-24 sortby-clz" labelPosition="top" prop="sortby">
									<u-radio-group iconPlacement="right" class="flex flex-wrap diygw-col-24 justify-between" wrapClass=" justify-between" v-model="form.sortby" :iconSize="16">
										<u-radio activeImg="/static/g.png" img="/static/g1.png" class="diygw-col-24" shape="circle" v-for="(sortbyitem, sortbyindex) in formData.sortbyDatas" :key="sortbyindex" :name="sortbyitem.value">
											{{ sortbyitem.label }}
										</u-radio>
									</u-radio-group>
								</u-form-item>
								<view class="flex flex-wrap diygw-col-24 flex6-clz">
									<button @click="resetForm" class="diygw-col-8 btn4-clz diygw-btn-default">重置</button>
									<button @click="submitForm" class="diygw-col-0 btn5-clz diygw-btn-default">确定</button>
								</view>
							</view>
							<view class="clearfix"></view>
						</view>
					</u-dropdown-item>
				</u-dropdown>
			</view>
		</u-form>
		<view class="clearfix"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				//用户全局信息
				userInfo: {},
				//页面传参
				globalOption: {},
				//自定义全局变量
				globalData: {},
				dropdowns0: '',
				dropdowns1: '',
				dropdowns2: '',
				dropdownsDatas0: [
					{ text: '', value: '0' },
					{ text: '新款商品', value: '1' },
					{ text: '活动商品', value: '2' }
				],
				dropdownsDatas1: [
					{ text: '默认排序', value: '0' },
					{ text: '好评排序', value: '1' },
					{ text: '销量排序', value: '2' }
				],
				dropdownsDatas2: [
					{ text: '综合排序', value: '0' },
					{ text: '总价从低至高', value: '1' },
					{ text: '总价从高至低', value: '2' }
				],
				form: {
					start: '',
					end: '',
					ucheckbox2: '',
					ucheckbox: [],
					ucheckbox3: [],
					ucheckbox1: [],
					sortby: '1'
				},
				formRules: {},
				formData: {
					startFocus: false,
					endFocus: false,
					ucheckbox2Datas: [
						{ value: '-1', label: '不限', disabled: false },
						{ value: '2', label: '50万以下', disabled: false },
						{ value: '3', label: '50-80万', disabled: false },
						{ value: '4', label: '80-100万', disabled: false },
						{ value: '5', label: '100-150万', disabled: false },
						{ value: '6', label: '150-200万', disabled: false },
						{ value: '7', label: '200-300万', disabled: false },
						{ value: '8', label: '300万以上', disabled: false }
					],
					ucheckboxDatas: [
						{ value: '1', label: '一室', disabled: false },
						{ value: '2', label: '二室', disabled: false },
						{ value: '3', label: '三室', disabled: false },
						{ value: '4', label: '四室', disabled: false },
						{ value: '5', label: '五室', disabled: false },
						{ value: '6', label: '五室以上', disabled: false }
					],
					ucheckbox3Datas: [
						{ value: '1', label: '一室', disabled: false },
						{ value: '2', label: '二室', disabled: false },
						{ value: '3', label: '三室', disabled: false },
						{ value: '4', label: '四室', disabled: false },
						{ value: '5', label: '五室', disabled: false },
						{ value: '6', label: '五室以上', disabled: false }
					],
					ucheckbox1Datas: [
						{ value: '1', label: '一卫', disabled: false },
						{ value: '2', label: '二卫', disabled: false },
						{ value: '3', label: '三卫', disabled: false },
						{ value: '4', label: '四卫', disabled: false },
						{ value: '5', label: '五卫', disabled: false },
						{ value: '6', label: '五卫以上', disabled: false }
					],
					sortbyDatas: [
						{ value: '1', label: '综合排序', checked: true },
						{ value: '2', label: '总价从低至高', checked: false },
						{ value: '3', label: '总价从高至低', checked: false },
						{ value: '4', label: '单价从低至高', checked: false },
						{ value: '5', label: '单价从高至低', checked: false }
					]
				}
			};
		},
		onShow() {
			this.setCurrentPage(this);
		},
		onLoad(option) {
			this.setCurrentPage(this);
			if (option) {
				this.setData({
					globalOption: this.getOption(option)
				});
			}

			this.init();
		},
		onReady() {
			this.$refs.formRef?.setRules(this.formRules);
		},
		methods: {
			async init() {
				await this.initResetform();
			},
			closeDropdowns() {
				this.$refs.refDropdowns.close();
			},
			changeDropdowns0(evt) {
				let item = this.dropdownsDatas0.find((item) => {
					return item.value == evt;
				});
				item && item.action && this.navigateTo(item.action);
			},
			changeDropdowns1(evt) {
				let item = this.dropdownsDatas1.find((item) => {
					return item.value == evt;
				});
				item && item.action && this.navigateTo(item.action);
			},
			changeDropdowns2(evt) {
				let item = this.dropdownsDatas2.find((item) => {
					return item.value == evt;
				});
				item && item.action && this.navigateTo(item.action);
			},
			changeFormUcheckbox2(evt) {},
			changeFormUcheckbox(evt) {},
			changeFormUcheckbox3(evt) {},
			changeFormUcheckbox1(evt) {},
			initResetform() {
				this.initform = JSON.stringify(this.form);
			},
			resetForm() {
				this.form = JSON.parse(this.initform);
			},

			async submitForm(e) {
				this.$refs.formRef?.setRules(this.formRules);

				this.$nextTick(async () => {
					let valid = await this.$refs.formRef.validate();
					if (valid) {
						//保存数据
						let param = this.form;
						let header = {};
						let url = '';
						if (!url) {
							this.showToast('请先配置表单提交地址', 'none');
							return false;
						}

						let res = await this.$http.post(url, param, header, 'json');

						if (res.code == 200) {
							this.showToast(res.msg, 'success');
						} else {
							this.showModal(res.msg, '提示', false);
						}
					} else {
						console.log('验证失败');
					}
				});
			}
		}
	};
</script>

<style lang="scss" scoped>
	.text1-clz {
		padding-top: 20rpx;
		font-weight: bold;
		padding-left: 20rpx;
		font-size: 28rpx !important;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.flex1-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.start-clz {
		flex: 1;
	}
	.text-clz {
		padding-top: 10rpx;
		font-weight: bold;
		padding-left: 20rpx;
		font-size: 28rpx !important;
		padding-bottom: 10rpx;
		padding-right: 20rpx;
	}
	.end-clz {
		flex: 1;
	}
	.ucheckbox2-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.flex2-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.btn-clz {
		background-color: #e2e2e2;
		padding-top: 20rpx;
		border-bottom-left-radius: 12rpx;
		overflow: hidden;
		color: #080808;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		border-top-left-radius: 12rpx;
		border-top-right-radius: 12rpx;
		border-bottom-right-radius: 12rpx;
		text-align: center;
		padding-right: 20rpx;
	}
	.btn1-clz {
		padding-top: 20rpx;
		border-bottom-left-radius: 12rpx;
		color: #fff;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		border-top-right-radius: 12rpx;
		margin-right: 0rpx;
		background-color: #ff5c47;
		margin-left: 10rpx;
		overflow: hidden;
		flex: 1;
		border-top-left-radius: 12rpx;
		margin-top: 0rpx;
		border-bottom-right-radius: 12rpx;
		margin-bottom: 0rpx;
		text-align: center;
		padding-right: 20rpx;
	}
	.ucheckbox-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.ucheckbox3-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.ucheckbox1-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.flex3-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.btn2-clz {
		background-color: #e2e2e2;
		padding-top: 20rpx;
		border-bottom-left-radius: 12rpx;
		overflow: hidden;
		color: #080808;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		border-top-left-radius: 12rpx;
		border-top-right-radius: 12rpx;
		border-bottom-right-radius: 12rpx;
		text-align: center;
		padding-right: 20rpx;
	}
	.btn3-clz {
		padding-top: 20rpx;
		border-bottom-left-radius: 12rpx;
		color: #fff;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		border-top-right-radius: 12rpx;
		margin-right: 0rpx;
		background-color: #ff5c47;
		margin-left: 10rpx;
		overflow: hidden;
		flex: 1;
		border-top-left-radius: 12rpx;
		margin-top: 0rpx;
		border-bottom-right-radius: 12rpx;
		margin-bottom: 0rpx;
		text-align: center;
		padding-right: 20rpx;
	}
	.sortby-clz {
		font-weight: bold;
		font-size: 28rpx !important;
	}
	.flex6-clz {
		padding-top: 20rpx;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		padding-right: 20rpx;
	}
	.btn4-clz {
		background-color: #e2e2e2;
		padding-top: 20rpx;
		border-bottom-left-radius: 12rpx;
		overflow: hidden;
		color: #080808;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		border-top-left-radius: 12rpx;
		border-top-right-radius: 12rpx;
		border-bottom-right-radius: 12rpx;
		text-align: center;
		padding-right: 20rpx;
	}
	.btn5-clz {
		padding-top: 20rpx;
		border-bottom-left-radius: 12rpx;
		color: #fff;
		padding-left: 20rpx;
		padding-bottom: 20rpx;
		border-top-right-radius: 12rpx;
		margin-right: 0rpx;
		background-color: #ff5c47;
		margin-left: 10rpx;
		overflow: hidden;
		flex: 1;
		border-top-left-radius: 12rpx;
		margin-top: 0rpx;
		border-bottom-right-radius: 12rpx;
		margin-bottom: 0rpx;
		text-align: center;
		padding-right: 20rpx;
	}
	.container21094 {
	}
</style>

个性化下拉菜单就是这样轻松完成的。因为默认下拉菜单只是很简单的单选式下拉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值