移动测试开发 动态生成 form 表单
为什么会使用到动态创建 form 表单?
有时候在项目中会遇到各种各样 form 表单,这个时候就可以使用动态创建 form 表单来高效完成工作。
form-create 的使用
form-create:form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。form-create 和 UI 框架配合使用,目前支持 3 个常用的 UI:ElementUI、Iview、Ant-design-vue,以上 3 种任选一种安装都 OK。
在使用插件的时候虽然功能强大,但是也避免不了一些插件的局限性。包括版本和环境影响,
那么接下来我们就参考以上插件的原理,实现自己的表单。
步骤一
首先创建所需要使用到的表单元素,然后通过创建模板和表单元素做关联,在对应的模板中可以设置表单元素的默认值,元素的大小,以及是否是必填项,还可以实现元素的顺序拖拽排序,数据格式如下:
cf_desc:用来设置该属性的描述
Id:字段的具体值为表单的 key
cf_type: 属性类型
cf_name:可以是表单的 lable
formItem: [
{
id: 1,
cf_key: "customkey_1",
cf_name: "属性1",
cf_desc: "213221",
cf_type: "date",
cf_size: "small",
is_required: 1,
default_value: null,
type_options: null,
cus_id: 1,
customkey_23: null,
rules: [
{
required: true,
message: "必填项不能为空",
trigger: "change"
}
]
}
]
步骤二
实现表单组件,在创建表单时选择相应的模板。使用 v-if 判断类型显示对应的元素,
这里需要注意的是使用 v-model 的时候,修改值可能会出现失效的情况,所以需要用 change 事件手动赋值。触发 Change 事件的时候需要使用 emit 向外抛出此方法,
<div v-for="item in formItem"
:key="item.id"
class="form-item">
<el-form-item :key="item.id"
:rules="item.rules"
:id="item.id"
:prop="item.id">
<template v-slot:label>
<label>
{{ item.cf_name }}
</label>
</template>
<el-date-picker v-if="item.cf_type === 'date'"
v-model="formData[item.id]"
type="date"
:size="item.size"
placeholder="请选择日期"
@user1="(value) => onchangeSelect(item, value)"></el-date-picker>
</el-form-item>
</div>
步骤三
引入 form 表单组件通过 props 传递相应的参数,绑定传出的 emit 事件手动修改 v-model 的值,
<el-form :model="formData"
:rules="formRules"
ref="formRef"
label-position="top"
size="small">
<fromItem :formData="formData"
:formItem="formItem"
@user2="onchangeSelect"></fromItem>
</el-form>
遍历 formItem 将对应的 id 添加到 formData 中,用来做最后的表单提交,和必填项的校验。
注意,此步骤一定要做,而且得赋初始值,即使初始值为空。否则会出现,输入框里面输入不到值进而拿不到值。
formItem.forEach(item => {
formData[item.cf_id] = item.cf_value || "";
})
formRules 是通过遍历 formItem JSON 串中是否设置了改属性是否必填,必填则添加进 formRules 中,trigger 通过该属性的类型判断判断是 blur 还是 change,如果要对该属性设置自定义的表单验证,可以通过该属性相对应的 id 设置相应的校验规则。
formItem.forEach(item => {
if (item.is_required) {
formRules[item.matterCustomAttribute.id] = [
{
required: item.is_required === 1,
message: "必填项不能为空",
trigger: ["input", "textarea", "number"].includes(item.matterCustomAttribute.cf_type) ? "blur" : "change"
}
];
} else {
item.rules = [];
}
})
最终效果
总结
任何场景下在使用任何插件,可以先评估自己的需求以及用途,通过调研一些开源的插件从而激发灵感,自己去实现的的时候,一方面可以很大程度的提高在使用过程中自定义性。通过阅读更多的源码来提高自己的编码水平。