form组件:
input text passworld
select
checkbox
radio
文本域
日期
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)
5. 在结合form表单v-model定义一个表单数据对象formData。
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值
{{ its.label}}
- 定义对象存储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: '今天'
},
],
},
{{ its.label
}}
{{ its.label
}}
效果图:
但是我们发现所有的表单都在一行,所以就需要添加el-row和el-col
代码:
在这里需要注意的是如果需要在一行中添加两个表单组件,则需要将formConfig结构改为数组类型。
然后在父组件中的formConfig中进行改变,将每一项全部改为数组类型,并且如果哪一行需要几个表单则在该数组中添加n个对象。
const emit = defineEmits<{ (e: 'FormEvent', val: any): void }>()
const RadioGroup = () => {
console.log(props.formData);
emit('FormEvent', props.formData)
}
将绑定的formData传递给父组件
{{ its.label
}}
{{ its.label
}}
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
})