数通互联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

138 lines
3.3 KiB

<!--
@ 作者: 秦东
@ 时间: 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>