给uniapp官网的级联选择器(uni-data-picker),添加搜索功能
今天是2024/7/11,我下载的版本是2.0.0 (仅兼容了本地数据版本)
1.实现效果:
2.下载并导入项目以后,是以下这个目录结构,按照这个目录我会告诉各位,我改了哪些文件的哪些代码。
3.首先是引入uni-data-picker组件的页面
//跟官网并无不同
<template>
<view >
<uni-data-picker :localdata="carTypeList" popup-title="请选择班级" @change="onchange" @nodeclick="onnodeclick" v-model="carTypeselect"></uni-data-picker>
</view>
</template>
4。uni-data-picker/comrponents/uni-data-pickerview/uni-data-pickerview.vue
总结一下,其实非常简单,html部分新增了一个Input,一个搜索出来的列表的展示
函数也增加了两个,一个是搜索后防抖出现搜索结果,另一个就是点击了某个搜索结果后,编辑成源代码需要的格式,并且调用源代码的更新方法即可!
新增代码贴在下面
<template>
<view class="uni-data-pickerview">
<!-- 全部新增,上面哪个搜索框 -->
<div style="padding: 20rpx;display: flex;">
<span style='height: 60rpx;line-height: 60rpx;'>搜索:</span> <input id='searchInput' v-model="searchValue" @input="handleInput" placeholder=" 请输入车辆类型"
style="border: 1rpx solid grey; flex: 1;border-radius: 10rpx;height: 60rpx;line-height: 60rpx;padding: 0 20rpx;" />
</div>
<!-- 新增一个view 将之前的tab和下面的选项给包起来,方便我们隐藏 -->
<view class="uni-data-pickerview" v-if="!searchContent">
<!-- 这以下都是源代码 -->
<scroll-view v-if="!isCloudDataList" class="selected-area" style="height: 50px;flex: 0 0 auto;" scroll-x="true">
<view class="selected-list">
<view class="selected-item" v-for="(item,index) in selected" :key="index" :class="{
'selected-item-active':index == selectedIndex
}" @click="handleSelect(index)">
<text>{{item.text || ''}}</text>
</view>
</view>
</scroll-view>
<!-- 回显区域 -->
<!-- 这以下都是源代码 -->
<view class="tab-c">
<scroll-view class="list" style=" 1 1 auto" :scroll-y="true">
<!-- 源代码省略-->
</scroll-view>
<view class="loading-cover" v-if="loading">
<!-- 源代码省略-->
</view>
</view>
<!-- 全部新增,这个部分就是显示我们 -->
<view class="uni-data-pickerview" style="overflow: auto;" v-else>
<view>
<view v-for="(item,index) of searchList" :key="index">
<view style="padding: 40rpx 20rpx;margin:0 20rpx;border-bottom:1rpx solid grey" @click="chooseItem(item)">
<span>{{item.frist.text}}/{{item.second.text}}/{{item.third.text.substr(0,item.thirdSlice[0])}}</span>
<span style="color: red;">{{item.third.text.substr(item.thirdSlice[0],item.thirdSlice[1])}}</span>
<span>{{item.third.text.substr(item.thirdSlice[1])}}</span>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
//原生代码
import dataPicker from "./uni-data-picker.js"
// 新增一个节流函数,因为我们用的是Input,让他稍微节流一下(是在export default 外面,这样才能函数闭包)
function debounce(fn, wait) {
let timeout = null;
return function() {
let context = this;
let args = arguments;
// let callNow = !timeout;
// 取消上一个timeout
clearTimeout(timeout);
timeout = null;
timeout = setTimeout(() => {
fn.apply(context, args)
// if (timeout) clearTimeout(timeout);
}, wait);
};
}
export default {
data() {
return {
// 搜索字段
searchValue: '',
searchContent: false,//显示搜索结果
searchList: []//搜索出来的列表(数组)
}
},
methods: {
// 搜索函数 ,再搜索框输入以后就会调用,然后生成要渲染的搜索结果列表,渲染到页面上
// handleInput: debounce(function(e) { 如果看不懂这个,说明函数闭包的节流没学好,可以去补一下
handleInput: debounce(function(e) {
console.log('eeeeee', e.target.value)
// 如果有值,就让搜索内容展示
if (e.target.value) {
// 打开搜索 关闭原生展示
this.searchContent = true
console.log('this.localdata', this.localdata)
// 重置展示列表
this.searchList = []
// 这个是我们使用组件传递过来的本地数据,data里面是没有的,因为她放到uni-data-picker.js中了,这个无所谓,我们这里直接能调用到,只是给大家提个醒
this.localdata.forEach((a) => {
// 这里面的逻辑就因大家而异了,因为我的数据结构是三级的,而且我必定传最后一级的value,所以我是这么写的,各位要自己根据自己的数据结构设计以下
a.children.forEach(a2 => {
a2.children.forEach(a3 => {
// 获取搜索匹配字段的最开始的位置,
let sliceStart = a3.text.indexOf(e.target.value)
if (sliceStart > -1) {
// 获取搜索匹配字段的最后的位置,是用于高亮搜索词语用的
let sliceEnd = sliceStart + e.target.value.length
// 最后我编辑出来的数据结构就是这样
let item = {
frist: {
text: a.text,
value: a.value
},
second: {
text: a2.text,
value: a2.value
},
third: {
text: a3.text,
value: a3.value
},
thirdSlice: [sliceStart, sliceEnd]
}
// 将他push到我的展示列表即可
this.searchList.push(item)
}
})
})
})
} else {
// 如果没有搜索词,那么就回到原始的展示
this.searchContent = false
}
}, 1000),
// 点击搜索选项后调用的函数
chooseItem(e) {
console.log('e.value', e.value)
// 为什么这个结构?因为别人封装好了方法,就是需要这个结构
let reinit = [e.frist, e.second, e.third]
// 调用父级的更新函数,不需要懂,别人封装好的
this.$emit('change', reinit)
// 把搜索内容不显示
this.searchContent = false
},
}
}
</script>
这就结束了我只更改了一个页面