移动端ui库uv-ui实现弹窗式picker选择控件
实现效果:点击表单框,弹出弹窗,支持接口查询数据,支持根据关键词过滤数据,点击弹窗里的单行回填到表单,支持清空已选内容,支持进入页面表单默认回填上次已保存的内容。
选择之后的表单效果 :
新建组件文件:cm-picker-popup.vue
<template>
<view>
<view class="input_style flex-between">
<view style="flex: 1" @click="itemChange">
<text v-if="showName">
{{ showName }}
</text>
<text v-else class="placeholder">请选择</text>
</view>
<image
v-if="showName && clearable"
class="img_s"
src="@/static/icon/delete1.png"
@click="onClear"
></image>
</view>
<uv-popup
ref="pickerPopup"
mode="bottom"
round="15"
closeable
custom-style="height: 700rpx;"
>
<view class="picker_popup">
<view v-if="search">
<uv-input
v-model="name"
placeholder="请输入名称查询"
@input="onSearch"
clearable
/>
</view>
<view class="picker_popup_content">
<view
v-for="(item, index) in optionData"
:key="index"
class="picker_popup_item"
@click="onSelect(item)"
>
<text v-if="optionCode">{{ item[optionCode] }}-</text
>{{ item[optionLabel] }}
</view>
</view>
</view>
</uv-popup>
</view>
</template>
<script>
export default {
name: "CmPickerPopup",
props: {
value: [String, Number],
apiConfig: String,
apiParams: Object,
optionConfig: Object,
search: Boolean,
clearable: {
type: Boolean,
default: true,
},
},
data() {
return {
showName: "",
optionData: [],
name: "",
};
},
computed: {
_optionConfig() {
return Object.assign(
{
label: "label",
value: "value",
},
this.optionConfig
);
},
optionCode() {
return this._optionConfig.code;
},
optionValue() {
return this._optionConfig.value;
},
optionLabel() {
return this._optionConfig.label;
},
},
watch: {
value: {
immediate: true,
async handler(val) {
if (val) {
await this.queryList();
const data = this.optionData.find(
(item) => item[this.optionValue] === val
);
this.showName = data[this.optionLabel];
}
},
},
},
created() {},
mounted() {},
methods: {
// 获取数据
queryList(params) {
const suggestValue = params ? params : "";
const { apiConfig } = this;
return this.request[apiConfig]({ ...this.apiParams, suggestValue })
.then((res) => {
this.optionData = res;
})
.catch((res) => {});
},
// 打开
itemChange() {
this.$refs.pickerPopup.open();
this.name = "";
this.queryList();
},
// 搜索
async onSearch(name) {
this.queryList(name);
},
// 选择
onSelect(item) {
this.showName = item[this.optionLabel];
this.$emit("input", item[this.optionValue]); // 触发 input 事件
this.$emit("onSelect", item);
this.$refs.pickerPopup.close();
},
// 删除
onClear() {
this.showName = "";
this.$emit("input", null); // 触发 input 事件
this.$emit("onClear");
},
},
};
</script>
<style lang="scss">
.input_style {
position: relative;
}
.placeholder {
color: rgb(192, 196, 204);
}
.picker_popup {
height: 100%;
padding: 80rpx 40rpx;
::v-deep .uv-input__content__field-wrapper__field {
text-align: left !important;
}
}
.picker_popup_content {
height: 510rpx;
overflow-y: scroll;
margin-top: 20rpx;
}
.picker_popup_item {
padding: 30rpx 0 5rpx 0;
border-bottom: 2rpx solid #f1f1f2;
color: #555 !important;
font-size: 32rpx;
}
</style>
组件全局注册:
import CmPickerPopup from "@/cusComponents/cm-picker-popup";
Vue.component("cm-picker-popup", CmPickerPopup);
组件使用:
<uv-form ref="form" :model="search" :label-width="100">
<uv-form-item label="申领单位" prop="agenCode" border-bottom>
<cm-picker-popup
v-model="search.agenCode"
api-config="queryAgen"
:api-params="{
all: true,
}"
:option-config="{
label: 'name',
value: 'id',
code: 'code',
}"
search
></cm-picker-popup>
</uv-form-item>
</uv-form>