ElementUI-Form表单二次封装

一、Form组件二次封装考虑组件构成:

  1. form组件:
  2. input text passworld
  3. select
  4. checkbox
  5. radio
  6. 文本域
  7. 日期

二、实现Form表单的二次封装:

1. 分析出对应的位置 开始抽离组件

2. 如果需要产生多个form表单,则需要产生多个el-form-item,则需要一个数据来循环渲染form-item

3. 结合form表单属性继续分析:

    - el-form-item:label 显示文本

    - 内部标签:el-input v-model绑定数据 placeholder 文本提示等等

4. 首先确认一个集合,配置内部属性:比如name,placeholder,type,size,width等等

其中name使用配置使用哪一种表单(input,elbutton)

ElementUI-Form表单二次封装_第1张图片

 5. 在结合form表单v-model定义一个表单数据对象formData。

ElementUI-Form表单二次封装_第2张图片

 ElementUI-Form表单二次封装_第3张图片

 6. 修改二次封装组件代码中循环formConfig配置产生form

     - 首先先要导入需要使用的element-ui组件

// 按需引入组件
import { ElInput, ElRadioGroup, ElRadioButton, ElDatePicker } from 'element-plus'

    - 配置formConfig表单配置集合,form-item循环该配置自动生成多个form-item,该formConfig是从父组件通过props传过来的值,所以需要使用defineProps来进行接收

interface propTypes {
    formData: any;
    formConfig: Array<{
        name: string;
        placeholder?: string;
        label?: string;
        key: string;
        type?: string;
        size?: string;
        width?: string
        children?: Array<{
            label: string
            value: string
        }>
    }>
}
const props = defineProps()

注意:因为form-item需要循环formConfig,所以formConfig为数组类型。

 扩展:这里需要注意的是如果需要给defineProps设置默认值(el-table组件的二次封装需要设置默认值)时,使用withDefaults()

interface PropType {
   tableData?: Array
   columnKey?: Array,
   title: Array,
   border?: Boolean,
   // 分页参数:
   pageSizes?: Array,
   layout?: string,
   total?: number
}
const props = withDefaults(defineProps(),{layout:'total, prev, pager, next,sizes',total:18,pageSizes:()=>[5,10,15,20]})

        - 在template组件中循环生成form-item

7. 分析简易封装之后的代码,得知el-input不是固定的,需要根据配置中的key动态切换,可以使用vue中component组件的动态挂载来完成

相当于因为循环的是formConfig,而formConfig中的key值是需要绑定的key值,也就是后端需要请求的字段,然后formData对象中存储的刚好是后端需要的字段所以根据对象的中括号来获取key值

 

 

        -  定义对象存储UI组件

interface UIComType{
    [propName:string]:any
}

let UICom:UIComType = {
    ElInput:ElInput
}

这里需要使用TS对UICom做类型限制否则在动态挂载组件时会报错。这里对属性值不明确的情况下使用[propName:string]:any

8. 父组件使用

        - 在父组件中配置form表单配置:

const formConfig = [
    {
        name: 'ElRadioGroup',
        label: '时间选择:',
        key: 'data',
        type: 'DatePick',
        width: '6',
        children: [
            {
                value: '',
                label: '全部'
            }

        ],

    }
]

        - 在组件中配置form表单数据源:formData: 绑定form表单中的数据,form表单根据key值来配置v-model的值,这里form表单中的元素都是后端需要请求的字段

const FormData = ref({
    paid: '',
    extract_type: '',
    nickname: '',
    data: '',
    page: 1,
    limit: 5
})

        - 导入form表单组件并动态绑定formConfig、formData



效果图:

 9. 若像是el-select、el-radio-group需要子项,则需要在formConfig中添加children数组,封装组件这里需要对这种包含子项的组件使用component组件动态加载并使用判断。

{
        name: 'ElRadioGroup',
        label: '时间选择:',
        key: 'data',
        type: 'DatePick',
        width: '6',
        children: [
            {
                value: '',
                label: '全部'
            },
            {
                value: 'today',
                label: '今天'
            },

        ],

    },

                    
                   
                        
                        
                    
                

效果图:

 但是我们发现所有的表单都在一行,所以就需要添加el-row和el-col

 代码:

ElementUI-Form表单二次封装_第4张图片

 在这里需要注意的是如果需要在一行中添加两个表单组件,则需要将formConfig结构改为数组类型。

ElementUI-Form表单二次封装_第5张图片

 然后在父组件中的formConfig中进行改变,将每一项全部改为数组类型,并且如果哪一行需要几个表单则在该数组中添加n个对象。

ElementUI-Form表单二次封装_第6张图片

 form二次封装表单使用$emit来向父组件传递值:

const emit = defineEmits<{ (e: 'FormEvent', val: any): void }>()
const RadioGroup = () => {
    console.log(props.formData);
    emit('FormEvent', props.formData)
}

将绑定的formData传递给父组件

form表单二次封装的整体代码:





父组件使用代码:

 
const formConfig = [
    [{
        name: 'ElRadioGroup',
        label: '时间选择:',
        key: 'data',
        type: 'DatePick',
        width: '6',
        children: [
            {
                value: '',
                label: '全部'
            },
            {
                value: 'today',
                label: '今天'
            },
            {
                value: 'yesterday',
                label: '昨天'
            },
            {
                value: 'week',
                label: '本周'
            },
            {
                value: 'month',
                label: '本月'
            },
            {
                value: 'quarter',
                label: '本季度'
            },
            {
                value: 'year',
                label: '本年'
            },

        ],

    },
    {
        name: 'ElInput',
        label: '搜索:',
        placeholder: '请输入用户昵称,订单号',
        key: 'nickname'
    }
    ],

    [{
        name: 'ElRadioGroup',
        label: '支付类型:',
        key: 'paid',
        type: 'DatePick',
        width: '6',
        children: [
            {
                value: '',
                label: '全部'
            },
            {
                value: '1',
                label: '已支付'
            },
            {
                value: '0',
                label: '未支付'
            },
        ],

    }],
    [{
        name: 'ElInput',
        label: '搜索:',
        placeholder: '请输入用户昵称,订单号',
        key: 'nickname'
    }]
]
const FormData = ref({
    paid: '',
    extract_type: '',
    nickname: '',
    data: '',
    page: 1,
    limit: 5
})

你可能感兴趣的:(elementui,前端,javascript)