网站首页 > 技术文章 正文
作者:徐小夕
转发链接:https://mp.weixin.qq.com/s/OYlLXp9bcwxM2q4c8A_FvQ
前言
之前笔者有写过一篇如何设计动态表单配置平台的文章,但是由于笔者电脑问题代码丢失,所以后期重新实现了一套表单设计器,并优化了之前的设计方式,特地做一下总结和复盘。
还有就是前段时间小编也发布一篇关于H5-Dooring 优质文章(含源码):
用React+Koa实现H5在线可视化编辑器-Dooring
你将收获
- 动态表单开发的一般思路
- 可视化领域中的表单引擎
- 从零实现一款动态表单设计器
- 利用H5-Dooring开发一款表单设计平台
正文
按照习惯,我们先看看表单设计器实现的效果展示:
上图中我们将表单设计器集成到了H5-Dooring中,使其可以实现拖拽生成表单。
其次我们可以根据右边的配置项,动态的添加某个表单组件或或者修改组件字段和数据源。在配置好表单之后我们还可以定制表单提交的api接口地址,以便实现用户数据的可溯源性。
在开发之前,我们先分析一下动态表单设计的一般实现思路。
动态表单开发的一般思路
1. 静态化配置列表
静态化配置列表是最传统的表单配置方式之一,基本思路就是利用母表来生成配置项,进而实现表单配置。类似于以下方式:
早期的网站配置就是类似于这种呢方案实现的,比如说我们要定制网站的主色,网站某些组件是否可见,是一种比较简单的方式。但是缺点是每增加一个配置属性,都要开发人员重新编写一个字段配置代码,这种方式在表单开发中非常不灵活,而且对代码层有强依赖性,所以只适合做小型配置系统。比如个人网站,简单的自定义表单。
2. 基于json schema的动态表单配置
基于json schema的动态表单配置有两种实现方案, 一种就是支持在线修改json文件从而实现定制化,另一种就是完全无代码操作,但是前提都需要提供一套通用的表单模版。类似于如下案例:
此种方案可以实现基本的表单自治。也是本文主要实现的方案。至于在线编写json文件的方案。笔者之前也也过成熟的方案,具体可以参考:
基于jsoneditor二次封装一个可实时预览的json编辑器组件(react版)
3. 支持在线coding的混合式表单设计
支持在线编程的混合式表单设计方案是终极方案,也是目前流行的无代码化平台的思想之一。一方面它提供了基于json schema的动态表单配置, 对于一些强定制的,需要在线设计组件方案的模式,采用在线编程,实时打包成动态组件的方式,最后根据平台的组件约定来实现组件库的方式。如下图所示:
在线代码编辑可以使用react-codemirror2或者 react-monaco-editor插件来实现。至于在线打包,我们用nodejs完全可以实现,笔者在做Dooring项目的在线下载代码时就用到了该方案,感兴趣的可以了解一下。
可视化领域中的表单引擎
可视化领域一方面强调的是图形(可视化)的设计,一方面是动态表单。比如说我们想傻瓜式的改变一张图的数据,属性,交互等,我们需要通过表单这一桥梁来实现:
所以我们需要设计一款适合公司产品的“表单引擎”,来动态根据图形组件的类型渲染不同表单配置。这块思想也是表单设计器要解决的问题之一。在下面的文章中我们会详细介绍实现过程。
从零实现一款动态表单设计器
在实现表单设计器之前,我们先来整理一下思路和需求。在笔者的最初草图中,它长这样:
从草图中我们可以提取到如下任务信息:
- 定义一套表单组件库
- 确定表单全局属性配置
- 实现表单操作curd(增删查改)
我们这里总结了几个常用的表单组件如下:
- 单选框
- 复选框
- 单行文本
- 多行文本
- 下拉框
- 文件上传
- 日期框
- 数值输入框
以上这些基本满足我们的日常开发需求,其次我们还可以开发数据源表单组件,列表组件,比如dooring实现的那样:
类似的还有颜色面板这些,我们可以根据业务需求自行定制。
在完成表单组件库之后,我们就需要根据配置项动态渲染了。也有两种实现思路,一种就是类似于多条件判断,如下:
{
item.type === 'Number' &&
<Form.Item label={item.name} name={item.key}>
<InputNumber min={1} max={item.range && item.range[1]} step={item.step} />
</Form.Item>
}
{
item.type === 'Text' &&
<Form.Item label={item.name} name={item.key}>
<Input />
</Form.Item>
}
{
item.type === 'TextArea' &&
<Form.Item label={item.name} name={item.key}>
<TextArea rows={4} />
</Form.Item>
}
复制代码
这样做虽然可行,也有很多成熟系统采用该方案,但是一旦表单变多,比如一个页面有几十个甚至上百个表单项,那么我们将渲染m * n次(m为表单组件类型数,n为配置项个数)。另一种方式笔者看来是比较优雅的,可以将复杂度降低到O(n),也就是笔者常用的对象法。思路大致如下:将表单组件的类型作为对象的属性,属性值为对应的表单组件,这样遍历的时候只需要对应上对象的具体类型即可。 代码如下:
// 维护表单控件, 提高form渲染性能
const BaseForm = {
"Text": (props) => {
const { label, placeholder, onChange } = props
return <Cell title={label}>
<Input type="text" placeholder={placeholder} onChange={onChange} />
</Cell>
},
"Number": (props) => {
const { label, placeholder, onChange } = props
return <Cell title={label}>
<Input type="number" placeholder={placeholder} onChange={onChange} />
</Cell>
}
}
// 动态渲染表单
{
formData.map((item, i) => {
let FormItem = BaseForm[item.type]
return <div className={styles.formItem} key={i}>
<FormItem {...item} />
</div>
})
}
复制代码
是不是很优雅呢?后期我们只需要在BaseForm里维护表单组件即可,而且还可以基于BaseForm对表单进行包装,实现动态删除,编辑等功能。如下:
包装后的代码如下:
<div>
<div className={styles.disClick}><FormItem {...item} /></div>
<div className={styles.operationWrap}>
<span onClick={handleEditItem}><EditOutlined /></span>
<span onClick={handleDelItem}><MinusCircleOutlined /></span>
</div>
</div>
复制代码
接下来我们看看表单的全局属性,通过实际分析我们可以知道表单有如下外观:
- 表单标题
- 表单背景图片
- 表单背景颜色
- 提交按钮样式
所以他们应该成为表单设计的通用属性,如下图所示:
配置出来之后的表单可能长这样:
以上的表单通过H5-Dooring设计而来。当然我们可以利用它设计更加自定的表单页面。
最后一个比较实用的需求就是api定制,一般公司可能需要将用户的录入数据收集到自己的平台,那么这个时候我们提供一个api表单提交接口积极很有必要了,上面笔者也展示过,实现很简单,就是配置里多一个api的文本框即可。
最后一步就是实现表单的curd操作,展示如下:
编辑表单项:
删除表单项:
添加表单项:
具体实现也比较简单,只需要基于BaseForm进行包装,添加删除/编辑/添加按钮即可。具体可以参考我的开源项目H5-Dooring,地址:H5-Dooring传送门
利用H5-Dooring开发一款表单设计平台
在H5编辑器Dooring的实现中,我们可以做抽象,每一个页面组件可以看成特定的表单组件,如下图:
我们可以利用dooring的能力对表单平台进行拖拽,样式设计,数据录入等等操作,感兴趣的朋友可以基于Dooring设计思路改造成自己的表单设计平台。在文末笔者会附上dooring的github地址供大家研究参考。
H5可视化编辑器Dooring功能迭代说明
目前笔者实现的H5可视化编辑器H5-Dooring功能新增如下:
- 实时保存功能
- 添加进度条组件
- 添加websocket通信
- 实现在线下载代码功能
- 添加Button组件
- 添加动态表单设计器
作者:徐小夕
转发链接:https://mp.weixin.qq.com/s/OYlLXp9bcwxM2q4c8A_FvQ
猜你喜欢
- 2024-11-17 fastapi+vue3文件上传(vue ftp上传)
- 2024-11-17 从零开始构建PDF阅读器(最简单的pdf阅读器)
- 2024-11-17 在 FastAPI 中处理表单和用户输入:综合指南
- 2024-11-17 Laravel9表单的验证(validate表单验证)
- 2024-11-17 第63节 Form表单-Web前端开发之JavaScript-王唯
- 2024-11-17 Gateway结合Sentinel1.8限流熔断及自定义异常
- 2024-11-17 手机网站常见问题总结(手机网站出现错误怎么办)
- 2024-11-17 CSS实现去除Input框默认样式的详细教程
- 2024-11-17 企业必备实战之Sentinel规则Nacos持久化
- 2024-11-17 禁用qq浏览器数字文本框 鼠标滚轮滑动 数字加减
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-