天天看点

bootstrap表单拖拽生成器插件_UForm可视化表单搭建器

bootstrap表单拖拽生成器插件_UForm可视化表单搭建器

引题

记得在一次技术分享会上,嘉宾分享了这么一道公式:

配置模板 + 数据 = 最终产品。

这个公式适用于很多产品,比如电商广告生成器基于邮件模板来填充广告数据生成最终的广告邮件,比如简单的设计图转成代码工具基于拆分好的设计图坑位再填充具体图片生成最终的代码片段。我们知道UForm作为JSON Schema驱动的表单状态管理器,只需要有一份json schema数据就能轻易地渲染出表单,那么只需要有配置模板,就可以通过可视化的形式来生成这份json schema,也就有了本文要介绍的可视化表单搭建器。

简要介绍

为了对下面的内容能够有一个感官的认知,在这里先简要介绍一下可视化搭建工具整体布局以及功能介绍:

  • 左侧组件集合:单击/拖拽到预览区域即可
  • 中间预览区域:编辑态时可以选中组件修改组件配置、删除、拖拽排序;最终预览态时可看到发布之后的页面状态
  • 右侧组件配置:选中预览区域的某个组件进行配置
  • 右侧上方操作栏
  • 预览:切换中间预览区域(编辑/最终预览)两种状态
  • 保存:将预览区域配置好的数据保存
  • 源码:基于微软开源的 monaco-editor 实现,对于一些目前可视化无法覆盖或者未实现的都能利用源码形式实现
bootstrap表单拖拽生成器插件_UForm可视化表单搭建器

黑色主题表单编辑器界面

技术方案

一个好的产品除了要能满足自身功能需求之外,还需要满足:可扩展性、组件独立性等。可视化表单搭建器底层基于UForm渲染,但是UI层能够根据不同的上层(Antd/Fusion Next)进行特定的适配,同时表单字段组件、属性配置组件、预览组件又是相互独立的,整体再通过Provider包装起来。​

bootstrap表单拖拽生成器插件_UForm可视化表单搭建器

可视化表单搭建器技术方案

技术实现

为了数据能够在多个组件之间简单的维护,技术实现上采用了

Redux

框架,reducers主要有以下几个:

  • initSchemaData:最核心的reducers,作为最终用于表单渲染的基础json schema数据
  • componentId: 维护当前正在编辑的组件ID
  • componentProps: 维护组件的属性数据,比如name/id/placeholder等数据
  • gbConfig: 维护表单全局属性,比如editable/itemCol等全局属性
  • codemode: 维护是否源码编辑状态
  • preview:维护是否预览状态

同时

components

结构上也按照功能拆分了几个组件:

  • fields: 组件类型列表,动态扩展(基于UForm的x-component任意注入组件)
  • preview: 核心渲染组件
  • props:属性配置组件

技术难点

Field颗粒度组件的可扩展

可视化表单搭建器是在UForm1.0版本的时候就开始在做了,当时是为了内部的一个项目使用。可视化表单搭建器里面的很多组件也都是表单,比如:

  • 组件的属性配置(组件name/id/placeholder等属性)
  • 核心预览模块(需要实时更新,既能进行拖拽排序/删除等操作也要能切换到最终渲染状态)

为了减少开发成本以及代码的可维护性,这部分表单直接用UForm进行渲染,但碰到了一个难点就是同一份json schema, 既要能直接用于渲染表单也要能注入一些HTML标签用于额外的操作。一开始想简单暴力用DOM操作强行注入需要的功能,但是这样子后续维护肯定很不方便,最好的解法是UForm组件支持动态注入,也就是现在开源版本的UForm已经实现的核心功能:

import 
           

联动处理

表单的联动是一个最常见的问题,UForm是引入了rxjs来实现时序性的联动,那可视化搭建器就需要生产出UForm用于联动的代码片段。关于可视化的联动处理感觉可以单独写一篇文章来详细介绍,等后面有时间再详细讨论。

多层嵌套的拖拽处理

拖拽的实现上用了开源的 react-dnd ,这玩意上手难度感觉不是很简单,必须要搞懂DragSource/DropTarget这两个概念才能玩懂。UForm的实现上有布局组件:Layout/Grid/FormItemGrid,在json schema的展现上如下:

映射到可视化配置,其实就是普通组件嵌套在布局组件里面。基于拖拽的方式就会碰到一个问题:一个布局组件A拖拽到另外一个布局组件B上,是要交换两者的顺序还是把A放到B里面?这会产生歧义。又或者布局组件A拖拽到布局组件B里面的普通组件C上,又需要做什么样的操作?

目前该问题还在解决中... 有更好的思路请告诉我感激不尽。 当然也想到了另外一种解法,那就是不用拖拽而改用更直观的箭头上下方式实现顺序交换/缩小树层级 -- 树操作,这种也不失为一种好的方式。

现状及未来规划

目前该可视化表单配置器用于内部可视化搭建系统以及业务的表单部分生成器,能够生产出标准的json schema用于上层组件的表单渲染,但是仅实现了最基础的功能(比如拖拽组件,然后编辑属性生成一份json schema),很多高阶功能还未完全实现(比如表单组件状态改变的hook自定义接入等)。当然两个方面的原因导致目前进度相对比较缓慢:一方面忙于业务没太多的时间精力投入,另一方面是底层的实现方案可能需要大改所以上层也不太敢动。

未来应该会整体技术重构改造,目前React Hooks其实已经能够cover住非重度复杂的应用。同时接入更多的自定义流程注入,这样子才能更好的满足实际表单的配置需要。