<template>
<component :is="getComponent()" class="full-width" v-bind="componentProps" />
</template>
<script setup name="DynamicInput">
import {
Input,
InputNumber,
DatePicker,
Select,
Cascader
} from 'ant-design-vue'
import SSelectFetch from '@/components/UIComponents/SSelectFetch'
import MultipleCascader from '@/components/MultipleCascader'
import { selectTreeNode, tableDataList } from '@/api/common'
import { useAttrs } from 'vue'
const props = defineProps({
item: {
type: Object,
default: () => {}
}
})
const componentsMap = {
String: Input,
Number: InputNumber,
Date: DatePicker,
Select: Select,
SearchSelect: SSelectFetch,
Cascader: Cascader,
MultipleCascader: MultipleCascader
}
const _propsMap = {
String: {
maxLength: 100,
placeholder: '请输入'
},
Number: {
placeholder: '请输入',
min: 0,
precision: 0
},
Date: {
type: 'date',
placeholder: '请选择日期'
},
Select: {
placeholder: '请选择'
},
SearchSelect: {
placeholder: '请输入关键字搜索',
fieldNames: {
label: 'name',
value: 'id'
}
},
Cascader: {
placeholder: '请选择',
fieldNames: {
label: 'name',
value: 'id',
children: 'children'
}
},
MultipleCascader: {
placeholder: '请选择',
fieldNames: {
label: 'name',
value: 'id',
children: 'children'
},
maxTagCount: 1,
maxTagTextLength: 4
}
}
const districs = ref([])
async function loadDistricts() {
const { data } = await selectTreeNode({})
districs.value = data
}
function getComponent() {
const { className, multipleFlag } = props.item
if (className === 'Cascader') {
if (multipleFlag === 'Y') {
return MultipleCascader
}
return Cascader
}
return componentsMap[className]
}
const componentProps = computed(() => {
const { className, multipleFlag, sourceKey, showFlag } = props.item
const attrs = useAttrs()
const baseProps = { ..._propsMap[className], ...attrs }
if (className === 'Cascader') {
if (multipleFlag === 'Y') {
return {
...baseProps,
options: districs.value,
maxTagCount: 1,
maxTagTextLength: 4,
placeholder: '请选择地区',
fieldNames: {
label: 'name',
value: 'id',
children: 'children'
}
}
} else {
return {
...baseProps,
options: districs.value,
placeholder: '请选择地区',
fieldNames: {
label: 'name',
value: 'id',
children: 'children'
},
changeOnSelect: true,
showSearch: {
filter: (inputValue, path) => {
return path.some(
(option) =>
option.label.toLowerCase().indexOf(inputValue.toLowerCase()) >
-1
)
}
}
}
}
}
if (className === 'SearchSelect') {
return {
...baseProps,
data: (params) =>
tableDataList({
...params,
sourceKey: sourceKey,
showFlag: showFlag
})
}
}
return baseProps
})
onMounted(loadDistricts)
</script>
<style lang="scss" scoped>
.full-width {
width: 100%;
}
</style>
import DynamicInput from './DynamicInput.vue'
<a-col
v-for="(item, index) in formState.dynamicsList"
:key="item.id"
:span="6"
>
<a-form-item
:label="item.name"
:name="['dynamicsList', index, item.code]"
:rules="{
required: item.requestFlag === 'Y',
message: `请完善${item.name}`
}"
>
<DynamicInput :item="item" v-model:value="item[item.code]" />
</a-form-item>
</a-col>