写点什么

基于 Formily 的表单设计器实现原理分析 ​

发布于: 2021 年 08 月 27 日
基于 Formily 的表单设计器实现原理分析  ​

作者:段国伟、汪曦

背景

在控制台类 web 应用中,表单是最常见的交互形式。用户在表单中填写信息,点击提交就能完成对数据创建或者修改操作。


最开始前端开发人员根据业务模型和具体需求,通过逐一编写或者声明实现表单中的各个字段,测试通过之后发布上线。渐渐的,开发人员开始把一些常用的方法抽象成表单库复用,提升开发效率。但随着业务复杂度的增加和需求的不断演进,对表单的展示形式和灵活程度要求也在不断提高,现有的表单库只能解决部分问题,开发者仍需花费大量的精力在更新表单字段或者开发新表单上。


那有没有一种方式,既能让开发人员快速构建表单,同时在后期又很少或者根本不需要开发人员介入来更新表单呢?


此时,表单设计器应运而生。表单设计器提供了可视化界面,让非专业开发人员也能通过拖拽的方式,所见即所得的构建业务所需表单。

表单设计器样式

目前很多开源的表单设计器实现,在 UI 上都大同小异,设计器的结构类似设计软件的布局。表单设计器一般为左中右三栏布局:


  • 左侧是控件列表,列出了设计器支持的表单控件;

  • 中间部分是画布(canvas) ,左侧的控件可直接拖拽到画布中,并支持控件调整顺序、复制等操作;

  • 右侧是表单字段的配置区域,在画布中选中一个字段,右侧将展示此字段的所有属性,用户可在此处配置字段标题、描述、校验规则等。

原理解析

表单设计器的输出是一份描述表单字段的 JSON Schema,表单设计完成后 JSON Schema 将直接存储到后端。表单发布后,前端再根据 JSON Schema 渲染表单。表单中所有字段的信息都是存储在 Schema 中,所以每次对表单的更新都是修改 Schema 中的内容,无需传统的编译过程。借助表单设计器,不但将开发人员从应对业务变更的频繁改动中解放出来,同时大大提高了非专业开发人的生产力,较少了沟通成本。JSON Schema 是表单设计器和表单渲染组件之间沟通的语言。要理解表单设计器的核心,首先要理解 Schema。在实际的项目中,JSON Schema 一般比较复杂,此处不做展开。本文的主题是表单设计器的实现原理,主要关心的是如何提供一个可视化界面,让用户能够快速生成 Schema,Schema 的详细格式将在后续文章中介绍,这里先提供一个简化版本的定义:

interface Schema {  fields: Record<FieldKey, FieldSchema>;}
interface FieldSchema { title: string; type: 'string' | 'object' | 'array' | 'number' | 'boolean'; component: string; componentProps: { [name: string]: any; };}
复制代码


众所周知,表单由多个 input 控件组成,input 控件包含多种形式,如:文本、数字、单选和多选等。Schema 中除了描述字段对应的是哪种类型的 input 外,还需要描述控件的行为,例如是否限制输入长度,是否必填等。有了这些描述后,表单渲染组件才能根据 Schema 渲染出符合预期的表单。


在上面的类型定义中:

  • component 表示该字段用什么 input 组件渲染;

  • componentProps 表示传给组件的 props,用于控制组件的行为;

  • type 表示组件接受和期望返回的数据类型;

  • FieldKey 是字段在表单中的唯一标识,用户侧不透出;

  • title 表示表单中字段对应的 label,它的值用户可读。


表单设计器的任务就是从零开始,或者将已有的 JSON Schema 作为输入,对 Schema 中的字段做添加、删除和更新操作,最后输出 Schema。如果我们把表单设计器看成一个整体,那它的功能可以用下图表示:



整体来看,表单就是对每个控件的操作进行组合,组合的结果就是完整的 JSON Schema。


为了能够实现对表单字段的修改,我们在表单设计器中提供了字段配置区域,用户在配置区域中,可以通过可视化方式定义字段属性,而无需关心 Schema 的具体格式。表单设计器负责将配置值转化成 Schema,同时也负责将 Schema 转化成配置值,用来回显配置后的页面表单。


说明:

配置区域其实也是一个表单,每种类型的控件也都有自己特定的配置表单。想要完成上述功能,每种控件都需要实现两个方法:toConfig toSchema。这里用一个公式来表示这两种方法和 Schema 的关系,其中 configValue 用来给配置表单做回显。


FieldSchema => toConfig => configValue => toSchema => FieldSchema
复制代码


厘清了上述思路之后,我们再回到表单设计器的 UI 呈现上来。



左侧是设计器支持的控件列表,根据上面的分析,每个控件都需要提供控件名称、配置表单、toConfig toSchema 这四个接口的实现。中间的 canvas 负责展示 Schema 中的控件,同时需要处理用户的点击和拖拽事件。当用户点击 canvas 中的某个字段时,右侧的配置区域需要找到对应的配置表单并渲染出来。

总结

以上是表单设计器最核心的架构实现,还有一些实现上需要考虑的细节,如表单 Schema 定义解析等将在后续的文章中逐步阐述,请大家持续关注。


全象云低代码平台的表单设计器是基于 Formily 实现的。Formily 的灵活扩展能力和为业务而生的特性让我们钦佩,感谢 Formily 团队的贡献,希望我们后面也能为 Formily 贡献代码。

关于全象云

全象云平台(https://portal.clouden.io)是青云科技自主研发的低代码平台,是基于云原生、用于辅助构建企业各类数字化应用的工具和集成平台。


平台目前提供云上无代码和低代码两种应用开发模式,屏蔽了技术的复杂度。支持可视化设计器,让开发人员和业务用户能够通过简单的拖拽、参数配置等方式快速完成应用开发。同时集成了 IDaaS 身份认证能力、容器 DevOps 能力,支持企业存量业务与全象云业务融合。平台还包含丰富的开发接口和强大的插件机制,开发者可根据需要不断拓展平台的应用能力。


全象云的愿景是:在企业生产经营的各个象限、各个环节提供软件构件或支持服务。



发布于: 2021 年 08 月 27 日阅读数: 6
用户头像

还未添加个人签名 2021.08.23 加入

还未添加个人简介

评论

发布
暂无评论
基于 Formily 的表单设计器实现原理分析  ​