6 changed files with 227 additions and 63 deletions
@ -0,0 +1,138 @@ |
|||||
|
<!-- |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2023-07-14 16:43:37 |
||||
|
@ 备注: |
||||
|
--> |
||||
|
<script lang='ts' setup> |
||||
|
import { reactive, computed, watch, inject, ref } from 'vue' |
||||
|
import { |
||||
|
constFormProps, |
||||
|
constSetFormOptions, |
||||
|
objectToArray |
||||
|
} from '@/api/DesignForm/utils' |
||||
|
import { FormList } from '@/api/DesignForm/types' |
||||
|
const props = withDefaults( |
||||
|
defineProps<{ |
||||
|
data: FormList |
||||
|
modelValue?: null |
||||
|
disabled?: boolean |
||||
|
transformOption: Function |
||||
|
options?: any |
||||
|
type?: string |
||||
|
isCheckbox?: boolean |
||||
|
remoteMethod?: Function |
||||
|
}>(), |
||||
|
{ |
||||
|
options: () => { |
||||
|
return [] |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
const emits = defineEmits<{ |
||||
|
(e: 'change', val: string | number, name: string): void |
||||
|
(e: 'update:modelValue', val: any): void |
||||
|
}>() |
||||
|
const setOptionsList = ref() |
||||
|
const formProps = inject(constFormProps, {}) as any |
||||
|
const optionsList = computed(() => { |
||||
|
// 如果有使用了setOptions设置时使用setOption的 |
||||
|
if (setOptionsList.value) { |
||||
|
return setOptionsList.value |
||||
|
} |
||||
|
if (props.type === 'slot') { |
||||
|
// 作为input前后缀使用时,支持固定和字典取值、暂不支持数据源 |
||||
|
// 因formItem层获取不到slot层的相关参数,如需实际可自引入formItem里的getAxiosOptions |
||||
|
const dictVal = formProps.value.dict |
||||
|
if (dictVal && props.data.config?.optionsType === 2) { |
||||
|
const opt = dictVal[props.data.config?.optionsFun] |
||||
|
if (opt !== undefined) { |
||||
|
return objectToArray(opt) |
||||
|
} |
||||
|
} |
||||
|
return props.data.options |
||||
|
} else { |
||||
|
return props.data.options |
||||
|
} |
||||
|
}) |
||||
|
const formOptions = inject(constSetFormOptions, {}) as any |
||||
|
watch( |
||||
|
() => formOptions.value, |
||||
|
(val: any) => { |
||||
|
const opt = val[props.data.name] |
||||
|
if (val && opt !== undefined) { |
||||
|
setOptionsList.value = objectToArray(opt) |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
const value = computed({ |
||||
|
get() { |
||||
|
if (props.type === 'slot') { |
||||
|
return formProps.value.model[props.data.name] |
||||
|
} else { |
||||
|
return props.modelValue |
||||
|
} |
||||
|
}, |
||||
|
set(newVal: any) { |
||||
|
if (props.type === 'slot') { |
||||
|
emits('change', newVal, props.data.name) |
||||
|
} else { |
||||
|
emits('update:modelValue', newVal) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
const state = reactive({ |
||||
|
loading: false // 远程搜索加载状态 |
||||
|
}) |
||||
|
watch( |
||||
|
() => props.data.options, |
||||
|
() => { |
||||
|
state.loading = false |
||||
|
} |
||||
|
) |
||||
|
// 符合远程搜索 |
||||
|
const isRemote = computed(() => { |
||||
|
return !!( |
||||
|
props.data.control?.remote && |
||||
|
props.data.control?.filterable && |
||||
|
props.data.config?.optionsType === 1 && |
||||
|
props.data.config?.optionsFun |
||||
|
) |
||||
|
}) |
||||
|
// 远程搜索 |
||||
|
const remoteMethod = (name: string) => { |
||||
|
if (isRemote.value) { |
||||
|
state.loading = true |
||||
|
// 请求参数名,可使用config.queryName传进来 |
||||
|
const queryName = props.data.config?.queryName || 'name' |
||||
|
props.remoteMethod && props.remoteMethod({ [queryName]: name }) |
||||
|
if (props.data.control.remoteMethod) { |
||||
|
props.data.control.remoteMethod(name) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<template> |
||||
|
<el-select |
||||
|
v-bind="data.control" |
||||
|
:disabled="disabled" |
||||
|
v-model="value" |
||||
|
clearable |
||||
|
:multiple ="props.isCheckbox" |
||||
|
:loading="state.loading" |
||||
|
:remoteMethod="remoteMethod" |
||||
|
class="selectWidth" |
||||
|
> |
||||
|
<el-option v-if="data.config?.addAll" value="" label="全部" /> |
||||
|
<el-option |
||||
|
v-for="item in optionsList" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="transformOption(item.value, data.config?.transformData)" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</template> |
||||
|
<style lang='scss' scoped> |
||||
|
.selectWidth{ |
||||
|
min-width: 120px; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue