封装组件库-表单(1)
2023, Mar 07
实现表单的封装
基于Element-plus框架的Form表单组件进行封装。
实现的功能
- 实现配置型表单,通过json对象的方式自动生成表单
- 具备更加完备的功能,表单验证,动态删减表单,集成第三方插件(富文本编辑器)
- 用法更简单,扩展性强(配置项形式),可维护
- 能够进行弹框嵌套表单等多场景。
初始配置
- 注册路由组件form,配置为Container组件的子路由组件
- 采用路由懒加载,箭头函数异步引入组件。
- 注册通用组件from,为路由组件的子组件,以便组件间通信。
- 将通用组件form注册为全局组件
实现基础表单
- 设计接口类型:Element-plus的表单验证是基于async-validator的验证规则,复制src/interface.ts作为rule.ts,引入接口RuleItem作为表单验证的接口类型。
import {RuleItem} from './rule'
export interface FormOptions {
//表单项显示的元素
type: 'cascader' | 'checkbox' | 'checkbox-group' | 'check-button' | 'color-picker' |
'data-picker' | 'input' | 'input-number' | 'radio' | 'radio-group' | 'radio-button' |
'rate' | 'select' | 'option' | 'slider' | 'switch' | 'time-picker' | 'time-select' |
'transfer',
//表单项的值
value?: any,
//表单项label
label?: string,
//表单项的标识
prop: string,
//表单项的验证规则
rule?: RuleItem[],
//表单项的占位符
placeholder?: string,
//表单项特有的属性
attrs?: {
clearable?: boolean,
showPassword?: boolean,
disable?: boolean,
}
}
用户名输入框组件
- 父组件配置用户名输入框组件
<!-- 给子组件传递组件的配置项 -->
<my-form :options="options"></my-form>
let options: FormOptions[] =[
{
type: 'input',
value: '',
label: '用户名',
placeholder: '请输入用户名',
prop: 'username',
rule: [
{
required: true,
message: '用户名不能为空',
trigger: 'blur'
},
{
min: 2,
max: 6,
message: '用户名在2-6位之间',
trigger: 'blur'
}
],
attrs: {
clearable: true
}
}
]
- 子组件
<!-- 给表单组件绑定表单数据对象model和表单验证规则rules,关闭立即触发验证 -->
<el-form v-bind="$attrs" :validate-on-rule-change="false" :model="model" :rules="rules">
<!-- 遍历表单绑定prop和label -->
<el-form-item :prop="item.prop" :label="item.label"
v-for="(item,index) in options" :key="index">
<!-- 动态组件指定组件类型,绑定剩余传参,并采用v-model双向绑定 -->
<component
v-bind="item.attrs"
:is="`el-${item.type}`"
v-model="model[item.prop]"
:placeholder="item.placeholder">
</component>
</el-form-item>
</el-form>
import {FormOptions,FormInstance} from './types/types'
import cloneDeep from 'lodash/cloneDeep'
let props = defineProps({
// 表单的配置项
options: {
type: Array as PropType<FormOptions[]>,
required: true
}
})
let model = ref<any>({})
let rules = ref<any>({})
//初始化表单的方法
let initForm = ()=>{
<!-- 判断表单是否为空 -->
if(props.options && props.options.length) {
<!-- 用于接收表单数据和规则 -->
let m: any = {}
let r: any = {}
<!-- 遍历表单,获取数据和验证规则,prop为model所需的键名 -->
props.options.map((item: FormOptions)=>{
m[item.prop] = item.value
r[item.prop!] = item.rule as any
})
<!-- 进行深拷贝,复制数据备用 -->
model.value = cloneDeep(m)
rules.value = cloneDeep(r)
}
}
<!-- 在组件挂载时初始化表单 -->
onMounted(()=>{
initForm()
})
密码输入框组件
- 父组件配置密码输入框组件
let options: FormOptions[] =[
{
type: 'input',
value: '',
label: '密码',
placeholder: '请输入密码',
prop: 'password',
rule: [
{
required: true,
message: '密码不能为空',
trigger: 'blur'
},
{
min: 6,
max: 15,
message: '密码在6-15位之间',
trigger: 'blur'
}
],
attrs: {
showPassword: true,
clearable: true
}
}
]