本文主要讲解后台系统与表单相关的页面开发,并分析如何才能更好地、高效地开发。
技术栈
- React
- Antd
背景
Antd
以下我都将Ant Design 简称为 Antd
Ant Design是个服务于企业级产品的UI框架,主要可以用于中后台系统,它有基于React、Vue和Angular的实现。个人感觉Antd还是很强大的,API相当完善、全面,基本能实现你想要的各种功能。
表单
在开发普通的后台系统时,开发得最多的就是实体的 新建、编辑和详情页面,这三个页面有共通之处,也有不同之处,感觉有可以复用的地方,但是有些地方又需要特殊处理。
表单页如图:
详情页如图:新建、编辑、详情页与Form表单组件的关系
从上面的几个图中我们看出:
- 新建和编辑可以复用一个Form组件
- 新建时不传给Form组件数据
- 编辑时会请求后端实体的数据,传给Form组件,进行数据初始化
- 详情页照理说也可以用Form组件,但是,UI视图上面Form组件和详情页面会不一致,比如:详情页只是纯粹展示的div,而非各种表单控件了。
思考并进行实现
通过上面的调研,我们可以考虑把详情页、新建和编辑做成单独的页面,但是新建和编辑复用同一个Form组件,Form组件进行数据收集、展示、表单校验,额外的逻辑处理(比如新建、编辑的提交动作、跳转页面和数据过滤)可能会有不同,所以在新建、编辑页面进行分别的处理。
ok,我们看看Form表单代码实现: 更多详情看这里
<Form onSubmit={this.handleSubmit}><FormItem{...formItemLayout}label="E-mail">{getFieldDecorator('email', {rules: [{type: 'email', message: 'The input is not valid E-mail!',}, {required: true, message: 'Please input your E-mail!',}],})(<Input />)}</FormItem><FormItem{...formItemLayout}label="Password">{getFieldDecorator('password', {rules: [{required: true, message: 'Please input your password!',}, {validator: this.validateToNextPassword,}],})(<Input type="password" />)}</FormItem>
...
上面的代码是利用Antd表单实现的,这里会有一些问题:
- 平均一个表单控件用平均12~17行代码(不包含复杂逻辑和回调函数),在大型系统中,一个复杂的表单可能会有30~40个控件,怎么办? 写一个2000 行的Form.js文件吗?
- 如下写法,会出现冗余代码:
每个控件都要写
和FormItem
,会出现多次,而且格式一致getFieldDecorator
<FormItem{...formItemLayout}label="E-mail">{getFieldDecorator('email', {rules: [{type: 'email', message: 'The input is not valid E-mail!',}, {required: true, message: 'Please input your E-mail!',}],})(<Input />)}</FormItem>
- 详情页需要重写一套完全不一样的逻辑和UI,无法复用Form组件中的逻辑
- 如果有动态标签怎么办? 比如我遇到一个场景:页面中有一些字段是前端写死的,比如 用户名,密码等,还有一些字段,是用户上传一个模板文件,后端解析模板并返回给前端的,结构可能是这样:
{"name":"标签名1","type":1, // 1:文本框, 2:百分比,3:数字,4:金额,5:单选按钮,6:单选下拉框,7:多选按钮,8:多选下拉框,9:日期-单日,10:日期-区间"commonUse":true, //是否常用标签"requiredTag":true, //是否必填"placeholder":"这个是描述","option":[ //选择项会用到此字段{"id":1,"name":"名字","defaultOption":true, // 是否默认选中}]
}
更好的解决方案
- 为了避免一个Form超过1000行这种情况出现,我们应该把大型Form表单进行拆分
如下图,有个合同的Form表单,我们按照类型做如下拆分:
- 针对上面的其余问题,我们计划提取出这样一个公共组件:
- 组件接收:需要渲染表单的字段、初始数据、字段的控件类型等
- 能根据字段的不同的控件类型渲染不同的表单控件
- Select
- Input
- ...
- 详情页也能复用这个组件
- 具有可扩展性(比如Antd的API的方法在此组件中均能使用)
总结
后台系统中我们开发的大部分页面都是表单页(新建、编辑、详情),少部分是列表页,我们应该多考虑路由划分、数据层设计、业务组件拆分、公用组件设计与实现,如果这些方面做好了,积累一定的经验,以后开发后台系统一定会事半功倍。
Tip: 我准备在下期再详细讲解上面提到的表单公用组件的设计与实现。
下一期: => 基于React的表单开发的分析(下)
相关链接
https://ant.design/components/form-cn/