uniapp开发手机app,一个页面调用多次同一个下拉框子组件,保证同时间下拉框只打开一个(兄弟组件间的通讯))

1、业务需求:封装一个下拉框的组件,下拉框弹出时,下拉框下面有半透明遮罩,下拉框上面正常显示,效果如图:
在这里插入图片描述2、问题:当一个页面同时引用多次该组件时,下拉框和遮罩会同时存在彼此叠加
3、解决:
其实这个过程就是一个兄弟组件之间的通信问题,当有下拉框打开时,通知另外的下拉框都保持关闭状态。

父页面引用组件代码:

<template>
	<!-- 筛选框 -->
	<view class="searchBox">
		<view class="inline shopNum">商家总数<text class="blueText">{{shopCount}}</text></view>
			<dropDown :drpoDownName="'智能排序'" :selectorScrollList="industryBrand"></dropDown>
			<dropDown :drpoDownName="'时间筛选'" :selectorScrollList="time"></dropDown>
		</view>
		<!-- 筛选框结束 -->
	</view>
</template>

<script>
	import dropDown from '@/components/sm-org-dropDown/sm-org-dropDown'
	export default {
		data() {
			return {
				name: "orgShop",
			}
		},
		components: {
			dropDown
		},
	}
</script>

<style>

</style>

子组件代码:

<template>
	<!-- 灰色下拉选择框 -->
	<view class="dropDown">
		<view class="drpoDownName" @click="showList">{{drpoDownName}} <text :class="selected?'cuIcon-triangledownfill':'cuIcon-triangleupfill'"></text></view>
		<!-- 下拉可选列表 -->
		<view class="drpoDownSelector" v-if="selected">
			<scroll-view scroll-y="true" class="selectorScroll">
				<view class="selectorScrollList" :class="checkedId == item.id ? 'selectorScrollListChecked' : ''" v-for="(item,index) in selectorScrollList" :key="item.id" @click="onSelectorClick(item.id)">
					<text>{{item.value}}</text>
				</view>
			</scroll-view>
		</view>
		<!-- 遮罩层 -->
		<view class="mask" v-if="selected" @click.stop="close"></view>
	</view>
</template>

<script>
	export default {
		name: 'sm-org-dropDown',
		props:{
			drpoDownName:{
				type:String,
				default:''
			},
			selectorScrollList:{
				type: Array,
				default:[]
			}
		},
		data() {
			return {
				selected:false,
				checkedId:0,
				//给子组件定义一个不会重复的gid,用来标识每一个子组件
				gid:`sm-org-dropDown-${(new Date()).getTime()}${Math.random()}`
			}
		},
		created() {
		//在created的时候,给子组件放置一个监听,这个时候只是监听器被建立,此时这段代码不会生效
		//uni.$on接收一个sm-org-dropDown-show的广播
			uni.$on('sm-org-dropDown-show',(targetId)=>{
			//接收广播,当该组件处于下拉框被打开的状态,并且跟下一个被点击的下拉框的gid不同时,将该组件的下拉框关闭,产生一个互斥效果。
				if(this.selected && this.gid!=targetId){
					this.selected=false
				}
			})
		},
		//当子组件销毁的时候,将建立的监听销毁,这里不会影响代码效果,但是在多次反复引用组件时,会在根节点定义越来越多的监听,长此以往影响性能,所以在不用的时候及时销毁,养成好习惯
		beforeDestroy() {
			uni.$off('sm-org-dropDown-show')
		},
		methods:{
			showList(){
				this.selected = !this.selected
				//在下拉框被点击的时候发出一个广播,将被点击到的这个组件gid广播出去
				if(this.selected){
					uni.$emit('sm-org-dropDown-show',this.gid)
				}
			},
			onSelectorClick(id){
				// this.selected = false;
				this.checkedId = id
			},
			close (){
				this.selected = false
			}
		}
	}
</script>

<style>
	.mask{
		width: 100%;
		height: 100%;
		position:absolute;
		left:0;
		/* top:0; */
		background: rgba(0,0,0,0.5);
	}
	.dropDown{
		display: inline-block;
	}
	.drpoDownName{
		color: rgba(128, 128, 128, 1);
		font-size: 11px;
	}
	.drpoDownSelector{
		padding: 10px;
		position: absolute;
		left: 0;
		width: 100%;
		background-color: #FFFFFF;
		z-index: 2;
	}
	.selectorScroll{
		max-height: 200px;
	}
	.selectorScrollList{
		line-height: 45px;
		color: rgba(80, 80, 80, 1);
		font-size: 14px;
	}
	.selectorScrollListChecked{
		color: rgba(42, 130, 228, 1);
	}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值