自定义搜索下拉组件 支持模糊查询 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事件
-->