uniapp 扩展picker-view实现条件查询

因为选项值过多,需要动态查询,现有组件无法实现,将picker-view扩展了一下,支持条件查询,接口调用。

实现效果

注意:直接使用,样式可能不准,根据自己的实际情况进行样式调整

参数说明
params: 数据接口参数,必填
{
	url:  接口地址,
	method: 请求方式,默认'get',
	data: 接口参数,
	search: 额外的参数
},
options: 显示数据集 
{
	value: 实际值字段,
	name: 显示值字段
},
placeholder: 查询条件提示文字 默认"请输入查询条件"
maxSize: 显示选项数量最大值,默认 100

事件说明
@handlerChange: 确认时间,返回完整选项行数据
@close:关闭组件
  • 完整代码 SearchPickerView.vue
html 复制代码
<template>
	<view>
		<view class="header">
			<view class="header-input">
				<view class="header-icon"><uni-icons type="search" color="rgb(192, 196, 204)" size="18" /></view>
				<input class="" type="text" :focus="true" v-model="searchValue" :placeholder="placeholder" />
			</view>
			<text class="header-btn-text" @click="search">搜索</text>
		</view>
		<view class="content">
			<view class="popup-btn">
				<text class="popup-btn-text cancel-btn" @click="cancel">取消</text>
				<text class="popup-btn-text confirm-btn" @click="confirm">确认</text>
			</view>
			<picker-view v-if="visible" :indicator-style="indicatorStyle" @change="bindChange" class="picker-view">
				<picker-view-column>
					<view class="item" v-for="(item,index) in pickerData" :key="index">{{item.name}}</view>
				</picker-view-column>
			</picker-view>
		</view>
	</view>
</template>

<script>
	import HSoftConf from '@/libs/config.js'
	import util from '@/libs/util.js'
	export default {
		props: {
		  params:{
			  type: Object,
			  required: true,
			  default: () => ({
				  url: '',
				  method: 'get',
				  data:{},
				  search: 'code'
			  })
		  },
		  options: {
		    type: Object,
		    default: ()=>({
				value: 'value',
				name: 'name'
			})
		  },
		  placeholder: {
			type: String,
			default: '请输入查询条件'
		  },
		  maxSize: {
			  type: Number,
			  default: 100
		  }
		},
		name:"SearchPickerView",
		data() {
			return {
				searchValue:'',
				pickerData:[],
				visible: true,
				indicatorStyle: `height: 50px;`,
				resValue: '',
				resultData: []
			};
		},
		methods: {
			search(){
				this.pickerData = []
				this.resultData = []
				console.log(this.searchValue,"searchValue")
				if(this.searchValue){
					if('post' == this.params.method){
						this.params.data[this.params.search] = this.searchValue
						util.post(this.params.url,this.params.data).then(res => {
							console.log(res);
							if ("200" == res.data.code) {
								let row = res.data.data;
								this.setPickerData(row)
							} else {
								uni.showToast({
								    title: '查询失败,'+res.data.msg,
								    icon: 'none'
								});
							}
						}).catch(err => {
							console.log(err,err.errMsg)
							uni.showToast({
							    title: '查询异常,'+err.errMsg,
							    icon: 'none'
							});
						})
					}else{
						util.get(this.params.url+this.searchValue).then(res => {
							console.log(res);
							if(200 == res.data.code){
								let row = res.data.data;
								this.setPickerData(row)
							}else{
								uni.showToast({
								    title: '查询失败,'+res.data.msg,
								    icon: 'none'
								});
							}
							
						}).catch(err => {
							uni.showToast({
							    title: '查询异常,'+err.errMsg,
							    icon: 'none'
							});
						})
					}
					
				}else{
					uni.showToast({
					    title: '查询条件为空',
					    icon: 'none'
					});
				}
				
			},
			bindChange(e){
				console.log(e)
				this.resValue = e.detail.value
			},
			cancel(){
				this.$emit("close");
			},
			confirm(){
				console.log(this.resValue)
				if(this.resValue > 0){
					this.$emit("handlerChange",this.resultData[this.resValue-1]);
				}else{
					this.$emit("handlerChange");
				}
				this.$emit("close");
			},
			setPickerData(row){
				if(row && row.length>0){
					if(row.length > this.maxSize){
						uni.showToast({
						    title: '查询结果数量'+row.length+',只显示前'+this.maxSize+'条',
						    icon: 'none'
						});
					}
					this.pickerData.push({value:'',name:'请选择'})
					this.resultData = row
					for(let item in row){
						if(item >= 100){
							break;
						}
						let data = row[item]
						this.pickerData.push({value:data[this.options.value],name:data[this.options.name]})
						console.log(this.pickerData)
					}
				}else{
					uni.showToast({
					    title: '查询数据为空',
					    icon: 'none'
					});
				}
			}
		}
	}
</script>

<style scoped>
	.header{
		display: flex;
		padding: 10px;
		align-items: center;
		flex-direction: row;
		
	}
	.header-btn-text{
		padding-left: 10px;
		line-height: 36px;
		font-size: 14px;
		color: #333;
		cursor: pointer;
	}
	input{
		font-size: 14px;
	}
	.picker-view {
		width: 750rpx;
		height: 600rpx;
		margin-top: 20rpx;
		
	}
	.item {
		line-height: 100rpx;
		text-align: center;
		display: block;
	}
	.header-icon{
		padding: 0 8px;
	}
	.header-input{
		flex: 1;
		line-height: 36px;
		height: 36px;
		border-radius: 5px;
		background-color: rgb(248, 248, 248);
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: left;
	}
	.popup-btn{
		display: flex;
		align-items: center;
		justify-content: space-between;
		flex-direction: row;
		padding: 10px;
	}

	.content{
		display: flex;
		flex-direction: column;
		border-top: 1px solid #e5e5e5;;
	}
	.confirm-btn{
		color: #007aff;
	}
	.cancel-btn{
		color: #888;
	}
</style>
  • 组件使用
html 复制代码
<template>
<uni-popup ref="popupSearch" background-color="#fff">
	<view class="popup-content">
		<SearchPickerView @close="closeSearchPopup" @handlerChange="handerChangeMateriel" :params="searchMaterielParams" :options="materielOptions" :maxSize="10"></SearchPickerView>
	</view>
</uni-popup>
</template>
<script>
// 引入组件
import SearchPickerView from '../../../components/SearchPickerView.vue
export default {
		components: {
		  SearchPickerView
		},
		data() {
			return {
				searchMaterielParams: {
					url: "接口地址",
					method: 'post',
					search: 'name'
				},
				materielOptions: {
					value: 'id',
					name: 'name'
				}
				
			}
		},
		method:{
			openSearchPopup(){
				this.$refs.popupSearch.open('bottom');
			},
			closeSearchPopup(){
				console.log("closeSearchPopup")
				this.$refs.popupSearch.close()
			},
			handerChangeMateriel(value){
				console.log(value,"handerChangeMateriel")
			}
		}
</script>
相关推荐
赔罪几秒前
最大公约数和最小公倍数-多语言
java·c语言·开发语言·javascript·python·算法
火锅娃8 分钟前
在 wordpress 中简易目录插件添加滑动条
javascript·css·json·html5
SRC_BLUE_1710 分钟前
UPLOAD LABS | PASS 01 - 绕过前端 JS 限制
开发语言·前端·javascript
NetX行者11 分钟前
Vue3+Typescript+Axios+.NetCore实现导出Excel文件功能
前端·typescript·c#·excel·.netcore
美团测试工程师23 分钟前
Fiddler导出JMeter脚本插件原理
前端·jmeter·fiddler
喵喵酱仔__1 小时前
uniapp 地图移入的快,高亮显示两个
uni-app
余生H1 小时前
Angular v19 (二):响应式当红实现signal的详细介绍:它擅长做什么、不能做什么?以及与vue、svelte、react等框架的响应式实现对比
前端·vue.js·react.js·angular.js
聚宝盆_1 小时前
【记录:前端提高用户体验】
前端·css
GISer_Jing2 小时前
Vue前端进阶面试题(六)
前端·javascript·vue.js
YueiL2 小时前
数据结构每日一题|判断链表是否有环型结构
javascript·数据结构·链表