Uniapp封装自定义远程搜索下拉组件

自定义搜索下拉组件 支持模糊查询 uniapp+uView

下拉组件内容:
<template>
	<view class="contentBox">
			<u-popup height='50%' v-model="show" mode='bottom' @close='closedHandle'>
					<view class="searchBox">
						<u-search placeholder="请输入关键字查询" 
						v-model="keyword" 
						shape="square" 
						action-text='确认'
						:action-style="{ 'font-weight': '700', color: '#2661dc' }"
						@change='searchHandle'
						@custom='confirmHandle'
						></u-search>
					</view>
					<picker-view indicator-style="height: 40px;" :value="setValues" @change="bindChange" 
						style='display: flex;flex-direction: column;flex: 1;' :immediate-change='true'
					>
						<picker-view-column>
							<view class="listItem" v-for="(item,index) in listData" :key="index">
								{{item.name}}
							</view>
						</picker-view-column>
					</picker-view>
			</u-popup>
	</view>
</template>

<script>
	import debounce from '../../utils/debounce.js'
	export default {
		props:{
			dataSource: {
				type: Array,
				default () {
					return []
				}
			},
			pickerValues: { //picker默认展示的值
				type: Array,
				default () {
					return [0]
				}
			},
			isShow:{
				type:Boolean,
				default(){
					return false
				}
			},
		},
		data() {
			return {
				form: { //要传过去的值
					id: '',
					name: ''
				},
				setValues:[0],
				keyword:'',
				show:false,
				listData:this.dataSource,
				debouncedSearch: debounce(this.debounceFun, 500)//防抖处理
			}
		},
		watch: {
			dataSource: {
				handler(newValue, oldValue) {
					this.listData = newValue
					// console.log(newValue,'newVal')
				},
				deep: true,
				immediate: true,
			},
			isShow(newValue, oldValue){
				this.show=newValue
			}
		},
		onLoad() {
		},
		methods: {
			init() {
				this.$nextTick(() => {//组件渲染完成后在更新数据
					this.setValues = this.pickerValues
				})
			},
			  searchHandle(val) {
				this.debouncedSearch(val);
			  },
			  debounceFun(data) {
				this.$emit('searchHandle', data);
			  },
			confirmHandle(val){
				if (this.form.id == '' && this.list.length > 0) {
					this.form = {
						id: this.listData[0].id,
						name: this.listData[0].name
					}
				}
				this.$emit('recload', this.form);
				this.show=false
			},
			bindChange(e) {
				let value = e.detail.value.toString();
				this.listData.forEach((item, index) => {
					if (value == index) {
						this.form.id = item.id;
						this.form.name = item.name
					}
				});
			},
			closedHandle(){
				this.$emit('closeHandle', false);
			},
		}
	}
</script>

<style lang="scss" scoped>
	.contentBox {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		::v-deep .uni-scroll-view-content{
			display: flex;
			flex-direction: column;
			.searchBox{
				padding: 15px;
			}
			.listItem{
				display: flex;
				justify-content: center;
				align-items: center;
			}
			.uni-picker-view-mask{
				height:100% !important;
			}
		}
	}
</style>
对搜索的change事件进行防抖性能优化 debounce

注意:

每次调用searchHandle方法时都会创建一个新的debouncedSearch函数,因此无法实现防抖效果。

为了解决这个问题,我们可以将debouncedSearch函数作为组件的一个属性,并且在组件初始化时创建它,这样就能确保每次调用searchHandle时都是同一个函数。

export default function debounce(fn, interval = 500, immediate = false) {
  //fn为要执行的函数
  //interval为等待的时间
  //immediate判断是否立即执行
  var timeout; //定时器

  return function() {
    //返回一个闭包
    var context = this,
      args = arguments; //先把变量缓存
    var later = function() {
      //把稍后要执行的代码封装起来
      timeout = null; //成功调用后清除定时器
      if (!immediate) fn.apply(context, args); //不立即执行时才可以调用
    };

    var callNow = immediate && !timeout; //判断是否立即调用,并且如果定时器存在,则不立即调用
    clearTimeout(timeout); //不管什么情况,先清除定时器,这是最稳妥的
    timeout = setTimeout(later, interval); //延迟执行
    if (callNow) fn.apply(context, args); //如果是第一次触发,并且immediate为true,则立即执行
  };
}
父组件使用
			<RemoteSelect :isShow="ReportedselectShow2" :dataSource='ReportedselectList2' 
				@closeHandle='closeHandle' @recload='ReportedselectConfirm2' @searchHandle='searchHandle'
				></RemoteSelect>
        <!-- 
        	isShow 控制控件是否显示状态
        	dataSource 下拉的原始数据[ {name:'',id:''} ]
        	closeHandle    控件关闭时调用的函数 此处用于修改父组件的状态
        	recload  选择确认的事件
        	searchHandle  搜索change事件
				-->
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值