JSearchMultiSelectTag.vue
源文件
在使用JeectBoot(ant-design-vue)设计表单时,需要实现下拉搜索+下拉多选+表字典(支持条件查询)。
但是系统目前有两个组件分别是JMultiSelectTag
和JSearchSelectTag
。经测试发现:1.JMultiSelectTag
支持下拉多选+支持表字典(不支持条件查询)。2.JSearchSelectTag
支持下拉搜索+表字典(支持条件查询)。所以两者都不能满足。
因为在需求中主要以下拉搜索和表字典(支持条件查询为主),所以选择在JSearchSelectTag
的基础上进行调整,从而实现需求内容。
JMultiSelectTag.vue
文件1)复制src/components/dict/JMultiSelectTag.vue
目录的文件,然后重命名为JSearchMultiSelectTag.vue
2)修改组件名称
因为文件是直接复制来的,所以需要将名称改成自定义的组件名称JSearchMultiSelectTag
template
部分在a-select
标签内添加mode="multiple"
,即为添加多选的属性。因为不需要做大量的数据缓存,所以同步异步也是相差不大,即可以调整如下:value="selectedValue",@change="onChange"
<template>
<a-select
v-if="async"
mode="multiple"
showSearch
labelInValue
:disabled="disabled"
:getPopupContainer="getParentContainer"
@search="loadData"
:placeholder="placeholder"
:value="selectedValue"
v-model="selectedAsyncValue"
style="width: 100%"
:filterOption="false"
@change="onChange"
allowClear
:notFoundContent="loading ? undefined : null"
>
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
</a-select>
<a-select
v-else
mode="multiple"
:getPopupContainer="getParentContainer"
showSearch
:disabled="disabled"
:placeholder="placeholder"
:value="selectedValue"
optionFilterProp="children"
style="width: 100%"
@change="onChange"
:filterOption="filterOption"
v-model="selectedValue"
allowClear
:notFoundContent="loading ? undefined : null">
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
</a-select>
</template>
props
部分将props中的value类型改为string
props:{
disabled: Boolean,
value: String,
dict: String,
dictOptions: Array,
async: Boolean,
placeholder:{
type:String,
default:"请选择",
required:false
},
popContainer:{
type:String,
default:'',
required:false
},
pageSize:{
type: Number,
default: 10,
required: false
},
getPopupContainer: {
type:Function,
default: null
},
},
watch
部分监听输入框输入的value时,判断val为空时赋值SelectValue为空值,有输入值就取initSelectValue请求接口。
watch:{
"value":{
immediate:true,
handler(val){
if(!val){
this.selectedValue=[]
this.selectedAsyncValue=[]
}else{
this.initSelectValue()
}
}
},
"dict":{
handler(){
// this.initDictData()
this.initSelectValue()
}
},
'dictOptions':{
deep: true,
handler(val){
if(val && val.length>0){
this.options = [...val]
}
}
}
},
initSelectValue
部分methods中初始化选择框里的数据方法,查询较快,返回的数据会以逗号作为分隔符分割成数组,便利到options数组中,作为a-select-option
中选项。
initSelectValue(){
getAction(`/sys/dict/loadDictItem/${this.dict}`,{key:this.value}).then(res=>{
if(res.success){
let valueArr = this.value.split(',')
this.options = []
for(let r=0;r<res.result.length;r++){
let obj = {
value:valueArr[r],
text:res.result[r]
}
this.options.push(obj)
tis.selectedValue = valueArr
}
}
})
},
onChange
部分@onChange="onChange"
,当输入框有变化时,就可以自己根据需求将已选中的数据以逗号作为分隔符以字符串保存起来。
onChange (selectedValue) {
this.$emit('change', selectedValue.join(","));
},
注意:使用这种方法需要注意的是,表字典用到的表必须是数据库中实际存在的。