因为选项值过多,需要动态查询,现有组件无法实现,将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>