这里使用的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()
      })
    }
  },
  // 其他选项例如声明 propsemits。
  {
    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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注