微信扫码
与创始人交个朋友
我要投稿
表单的常用场景大致分为两类。
一个是 2C 的表单,一般是一次性的问卷类表单。比如调查问卷、信息收集、 报名汇总、打赏评价、评测考试等。
这类表单一般较为简单,设计上强调简洁和易用性。
另一类是 2B 的表单,主要是业务相关的单据填写。比如订单信息填写、工单创建、 各种业务数据的创建和编辑表单。
这类表单很多时候在布局和交互上都会很复杂,设计上要求可以高效的录入、准确性、以及体验一致性。
今天我们主要探讨 2B 的动态表单方案。
在B端业务中,表单作为数据收集与交互的重要手段,其重要性不言而喻。 然而,传统的表单开发方式面临着诸多挑战。
• 首先,表单开发中经常出现重复开发的情况,不仅增加了开发成本,还降低了开发效率;
• 其次,随着业务的不断演变,表单的维护成本也呈现出上升趋势;
• 此外,前后端校验不一致的问题也时有发生,严重影响了系统的稳定性和用户体验。
解决这些问题和挑战的常见方案是动态表单,一般是基于 Json 元数据描述表单结构, 动态渲染生成表单界面。
市面上虽然有很多成熟的动态表单产品, 但往往存在过于复杂、功能冗余的问题。 许多产品提供了大量不常用的功能,使得开发者在选择时难以抉择, 实际使用起来也难以定制,适配自己的业务时需要花费很多精力。 同时,这些产品在布局能力上也相对较弱,无法满足复杂表单的布局需求。 虽说提供了可视化可拖拽的设计器, 但是说实话,这样的设计在B端场景上并不高效。
这些问题不仅增加了开发者的学习成本,还限制了动态表单在实际应用中的灵活性和可扩展性。
下面推荐几个常见的动态表单工具:
• Baidu AMIS[1]
• Formily[2]
• Formik[3]
我们给出一个简单高效的动态表单方案(布局部分):
• 基于 CSS Grid 布局
• 使用 JSON 元数据描述表单结构
• 支持一行显示多个字段
• 支持复杂字段跨越多行
• 支持表单留白
为了美观,表单一般是等分对齐的。 CSS Grid 布局正好符合我们的需求。
查看 Tailwind CSS[4] 的示例, 我们可以看出所谓的等分对齐是什么意思。
我们还可以让某个元素占据多个单元格:
或者对表单进行留白:
甚至是让某个元素跨越多行:
我们既然说是高阶方案了,大家记着一句话,越高级的东西越简单。 我们今天要做的事情一样。
先定义一下元数据:
{
"columns": 1,
"fields": [
{"label": "姓名", "name": "name", "type": "text"},
{"label": "学号", "name": "code", "type": "text"},
{"label": "年龄", "age": "age", "type": "int"},
{"label": "描述", "name": "description", "type": "textarea"}
]
}
上面定义了表单是几列布局,以及字段的名称、类型等信息。
实现起来也很简单,比如使用 Vue 的 v-for
来循环生成字段,下面伪代码说明一下大致逻辑。
<template v-for="field in fields" :key="field.name">
<el-input v-if="field.type==='text'" :label="field.label" :model="model[field.name]"></el-input>
<el-input-number v-else-if="field.type==='int'" :label="field.label" :model="model[field.name]"></el-input-number>
<el-textarea v-else-if="field.type==='textarea'" :label="field.label" :model="model[field.name]"></el-textarea>
</template>
效果可能是这样的:
默认的多列支持可以给 Form 元素设置 grid-template-columns
样式属性, 比如两列就是:
'grid-template-columns': `repeat(2, minmax(0, 1fr))`
我们再程序里面动态设置:
<form :style="{'grid-template-columns': `repeat(${columns}, minmax(0, 1fr))`}">
效果大致如下:
如果需要字段跨多类,就可以增加一个 span
属性。
{"label": "描述", "name": "description", "type": "textarea", "span": 3}
多列的CSS样式使用 grid-column
属性,比如两列:
'grid-column': `span 2 / span 2`
跨越三列就是:
'grid-column': `span 3 / span 3`
我们重新定义表单:
{
"columns": 3,
"fields": [
{"label": "姓名", "name": "name", "type": "text"},
{"label": "学号", "name": "code", "type": "text"},
{"label": "年龄", "age": "age", "type": "int"},
{"label": "描述", "name": "description", "type": "textarea", "span": 3}
]
}
看下效果:
为了应对一些复杂控件比如 textarea,我们定义 colSpan 属性定义跨越的行数:
多行用 grid-row
样式属性来控制,我就不做解释了。
这样就能实现非常复杂的表单布局了,比如:
有些时候,我们希望某些字段留白,或者换行,可以使用 grid-column-start
属性来实现:
比如这样的表单:
从布局结构上来说,至此我们基本已经能够实现较为复杂的表单布局, 而且实现非常简单,核心代码不超过5行,无论你是用那种UI框架,都非常简单,且很容易扩展, 比如增加一些字段类型:
下篇文章介绍表单设计和如何使用AI进行表单辅助设计。
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-09-04
2024-09-06
2024-09-03
2024-08-18
2024-07-23
2024-11-19
2024-06-14
2024-09-02
2024-11-05
2024-07-19