这里使用的UI框架是ElementPlus,更换其他组件直接更换constant.ts中的type配置和对应的Form组件即可.
思路:
1.这里需要使用h函数方便控制要渲染的表单
2.传递type作为组件或html元素进行渲染,
3.默认包一层El-form,每个数组项会包一个El formItem
4.传入formDataKey,对绑定的表单项进行映射
export const DyForm = defineComponent(
(props, { emit }) => {
const form = computed({
get() {
return props.modelValue
},
set() {
return false
}
})
const rederChild = () => props.dyFormConfig.map((item: any) => {
const traverChildren = (child: any[]): any[] => {
return child.map(
item => {
if (typeof item.children === 'string') {
return h(item.type, item.children)
}
return h(item.type, item.formDataKey ?
{
...item.formConfig,
modelValue: form.value[item.formDataKey],
'onUpdate:modelValue': (value: any) => emit('update:modelValue', { ...props.modelValue, [item.formDataKey]: value })
} : item.formConfig,
{ default: () => item.children && traverChildren(item.children) })
}
)
}
const renderSlots = () => {
return Object.keys(item.slots).map((slot: any) => {
return item.slots[slot]()
})
}
return h(ElFormItem, { ...item.formItemConfig }, [
h(
item.type,
item.formDataKey ?
{
...item.formConfig,
modelValue: form.value[item.formDataKey],
'onUpdate:modelValue': (value: any) => emit('update:modelValue', { ...props.modelValue, [item.formDataKey]: value })
} : item.formConfig,
{
default: () => item.slots ? renderSlots() : traverChildren(item.children || [])
}
)
])
})
return () => {
return h(ElForm, {
model: form,
...props.formConfig
}, {
default: rederChild()
})
}
},
// 其他选项,例如声明 props 和 emits。
{
props: ['modelValue', 'onSubmit', 'dyFormConfig', 'formConfig'],
emits: ['update:modelValue']
}
)
export class UserForm {
name?: string
organization?: string
date1?: string
date2?: string
delivery?: boolean
type?: []
resource?: string
desc?: string
}
interface FormItemConfig<T>{
type:any
formConfig?: Record<string, any>
formDataKey?: T,
formItemConfig?: Record<string, any>
children?: FormItemConfig<T>[] | string
slots?:Record<string,()=>any>
}
export const dyFormConfig:FormItemConfig<keyof UserForm>[] = [
{
type: ElInput,
formItemConfig: {
label: '请输入姓名'
},
formConfig: {
},
formDataKey:'name'
},
{
type: ElSelect,
formItemConfig: {
label: '请选择组织'
},
formConfig: {
placeholder: '请选择您的组织'
},
formDataKey: 'organization',
children: [
{
type: ElOption,
formConfig: { label: '个人', value: 'person' }
},
{
type: ElOption,
formConfig: { label: '公司', value: 'company' }
}
]
},
{
type: 'div',
formItemConfig: {
label: "请选择时间"
},
formConfig: {
style: 'width:100%;display:flex;',
},
children: [
{
type: ElCol,
formConfig: {
span: 11
},
formItemConfig: {
label: '请选择日期'
},
children: [
{
type: ElDatePicker,
formDataKey: 'date1',
formConfig: {
type: 'date',
placeholder: '选择日期',
style: 'width: 100%'
}
}
]
},
{
type: ElCol,
formConfig: {
span: 2,
class: 'text-center'
},
children: [
{
type: 'span',
formConfig: {
class: 'text-gray-500'
},
children:'-'
}
]
},
{
type: ElCol,
formConfig: {
span: 11,
class: 'text-center'
},
children: [
{
type: ElDatePicker,
formDataKey: 'date2',
formConfig: {
type: 'date',
placeholder: '选择日期',
style: 'width: 100%'
}
}
]
}
]
},
{
type: ElButton,
formConfig: {
type: 'danger'
},
slots: {
default: () => '确认'
}
}
];
<script setup lang="ts">
import { DyForm } from './components/DyForm/DyForm';
import { dyFormConfig, UserForm } from './utils/constant'
const form = ref<UserForm>({
name: '',
organization: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
});
const onSubmit = () => {
console.log(form.value);
};
const formConfig = {
labelWidth: '120px',
style: {
width:'800px'
}
};
</script>
<template>
<DyForm v-model="form" :onSubmit="onSubmit" :dyFormConfig="dyFormConfig" :formConfig="formConfig" />
</template>
原文地址:https://blog.csdn.net/m0_47195133/article/details/134782879
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_38644.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。