我的 Serverless 实战 — 使用 formio 快速搭建表单类应用

本文以 React 为主,关于 Angular 的配置,我有在 b 战上面转载他们 CTO 做的教程,有需要的可以查看

Vue 就是真的完全没有了解了,因为我们项目本身就是用 React 搭建的,不过它们既然提供了 React Starterkit,Vue 应该也有差不多的配置。

formio 是什么

个人体感来说,formio 就是一个封装好了后台以及数据库的服务,使得开发成本相对而言比较低的工具。

根据个人过去小半年开发的经验,formio 整个一套体系可以走三个方向:

  • 使用 formio 全家桶

    这个就包括使用 formio 的平台服务(收费)搭配 formio 在 GitHub 上的一些开源项目

    全家桶的优势比较明确:

    • 有不同的 stages 可以进行不同的周期管理
    • 无需关注后台和数据库的实现,formio 平台已经提供了以 MongoDB 为存储方式的数据库,后台似乎是以 Java 实现的
    • 配置完成后基础的表单开发可以脱离程序员的控制——如果样式已经先行设定好了,那么业务人员可以直接实现表单的逻辑和呈现
    • 可以选择使用 formio 的平台 host 网站,或者也可以选择拉 docker 镜像独立部署

    全家桶的缺点相对而言也比较明显:

    • 如果存在业务需求比较复杂的情况下,那么手动添加复杂的逻辑判断必然会造成数据的冗余
    • 同样是在业务需求比较复杂的情况下,将所有的逻辑复制黏贴到所有的表单子项上面,这时候就应该担心人工错误了

    所以我觉得全家桶的应用范围主要还是在功能性不是特别复杂的,在做好样式之后不太需要开发人员参与的功能,比如说调研之类的。这应该也是为什么国内用 formio 平台的项目感觉不是很多的样子吧……类似的供应商,特别是有小程序集成的可太多了。

在缺点和优点同样比较明显的情况下,

  • 使用 formio 部分的服务

    • 仅仅使用 formio 的平台服务

      其实真的要说的话,formio 平台的价格还真的不是很贵,以能够支持部署的企业版为例,企业版包含了:formio 的 PAAS 部署,云部署(AWS 云的部署),每个项目表单无限,请求无限,提交有一百万个等,这样的费用是$250 一个月,合计 2000 人民币不到一个月

    • 或者是使用免费版的开源项目

      这种情况下,这里主要用的就是 formio.js 了,本质上来说,就是一个将表单的定义和内容以 JSON 的方式呈现及保存的一种方式

用 React 集成 formio

添加新项目

可以打开 formio 的官网:https://www.form.io/,注册一个账号,创建一个新的项目。

这是我创建的一个新的项目:

register-project

一创建就会默认生成 5 张表单:管理员登录、用户注册、用户登录,管理员和用户。其中后 2 张属于资源表,前 3 张属于业务表——在 formio 中,无论资源还是表单,其呈现形式都是都是表单,而表单的形式就是 JSON

简单地解释一下,一个完整的页面显示是这样的:

general

其中,Resource 资源是可配置的信息,以原生就有的信息举例,包括用户和管理员。直白一点的说,就是将数据库的信息傻瓜式地呈现出来。

Form 就是实际的表单,其实包括登录页面也是一个表单:收集用户名和密码,随后按钮点击传送到后台的一个简易表单。它可以与 Resource 互动,进行用户权限的管理,和对应数据的呈现。

配置 app

  1. 下载

    集成还是很简单的,因为配置方面(package.json)这方面其实不需要开发人员来配,formio 已经提供了一个 starter kit:react-app-starterkit。直接从 github 上拉下来,然后 npm install,下载安装所需要的依赖包即可

  2. 配置

    第二步,将新项目的 终点(endpoint),也就是访问接口配到项目之中。

    这需要在根目录下新建一个 config.js,将终点保存为变量:

    var PROJECT_URL = "https://tnoylkrhertcxwy.form.io";
    
  3. 运行

    这个时候,基本的项目就可以运行了——在这一步,并不代表可以使用

    运行后的效果图如下:

    running

配置用户

我这里新建一个管理员用户,可以走到 Resource > Admin,打开的页面如下:

admin-resource

其中:

  • Edit,负责表单呈现的效果
  • Use,可以直接在 formio 的平台上使用表单
  • Revisions,可以对表单操作的版本进行管理
  • API,fromio 会自动生成对应的 RESTful API,包含了 POST, INDEX, GET, PUT, DELETE,基本 CRUD 操作都在这里
  • Data,用户输入的数据
  • Actions,即这个表单可以有什么样的行为,包括不限于注册、登录、角色授权、OAuth、第三方登录等
  • Access,即谁能够访问这个表单,可以设置公开、验证用户、管理员。加上 formio 本身也能设置权限,可以根据需求添加新的权限组

这个情况下,我就直接用 Use 创建一个新的测试账号:

admin-user

表单创建

到 Form 的分栏,点击 New Form

new-form

选择 API Web Form。

new-form2

formio 另外也有创建 pdf 表单的功能,后者可以用来签订合同或是向用户提供排版好的信息进行交互,包括不限于合同、信息表等。

随后修改 Title——Name 和 API Path 会随着 Title 的变动而变动,如果有需求也可以手动修改

并且拖动左边的组件完成页面基础的布局

new-form3

这个表单中用了以下几个组件:

  • text field,对应 <input type="text">
  • email,对应 <input type="email">
  • text area,对应 <textarea>

点击保存后,表单就创建成功了

依旧选择 Use 先对表单进行校验,看看输入的信息格式是否正确,以及信息是否正确的存到了 Data 中

添加 Action

以发送邮件为测试,首先,点击 Actions 分区,从下拉框里面选出邮件,再点击 Add Action 新添加一个行为

随后,这个案例中只需要修改这个部分:

action1

这里用的是 mustache 的语法糖,data 是最终会被提交到数据库中的数据,email 就是刚才建立的 email 组件的 api,也是提交数据中的对应的键。

这就是收到的邮件了:

email

这是数据库中对应的数据:

email-data

有几点要注意的是,有一些 Action 免费版是没有办法使用的——当然,免费版只有 10 个表单,能用多少功能也不好说……

表单嵌入

首先,需要获取对应表单的 URL,基本的格式为:endpoint/api

这也可以在 API Path 上看到。

一旦获取了 API Path,就可以获取对应的表单定义(JSON 格式),再使用 formio 的库,就可以轻松将上面的表单完完全全的在 React 的项目中渲染出来:

const style = {
  margin: "100px auto",
  width: "250px",
};

ReactDOM.render(
  <div style={style}>
    <Form
      src="api-path"
      onSubmitDone={function (submission) {
        // do something
      }}
    />
  </div>,
  document.getElementById("root")
);

页面的实现效果如下:

react-form

可以说在 formio 的平台上看到的几无二致。

其他相关

动态的获取表单网址

我们的实现方法是这样的:

  • 建立一个资源与 role access 相关,其中限定了每个 role 所能够访问的模块
  • 建立一个模块资源,其中限定了每个模块中包含多少的表单

这样一来,我们并不需要手动的将所有的表单全都配置在 React 项目中,只需要业务人员在 formio 的平台上进行相关定义即可。

一旦有对应权限的成员登录到了页面之后,我们会根据其用户信息拉取对应的权限,再通过权限拉去对应的表单

表单中子项的设置

每一个 component 其实都是可配置的,从默认值、验证逻辑到隐藏条件,这些都是可以从 component 中配置的。

我也说了,在表单情况相对而言比较复杂的情况下,将所有的验证和隐藏条件全都放在平台上制作会有一定程度上的难度——不是实现的难度,而是保证准确率的难度。

除此之外,其他还能够加入对应的 API 类,对应的 CSS 类,这个就需要业务部门和开发部门讨论好具体的需求,开发部门可以进行配套的适配,然后业务部门的只要使用。

总体来说,这方面 formio 封装的还算挺完善的,至于使用的用户体验,就仁者见仁,智者见智了。

表单的样式,在可视化、可拖拽的界面上是这样的:

text-component

纯 JSON 格式是这样的:

{
  "label": "First Name",
  "tableView": true,
  "key": "firstName",
  "type": "textfield",
  "input": true,
  "placeholder": "",
  "prefix": "",
  "customClass": "",
  "suffix": "",
  "multiple": false,
  "defaultValue": null,
  "protected": false,
  "unique": false,
  "persistent": true,
  "hidden": false,
  "clearOnHide": true,
  "refreshOn": "",
  "redrawOn": "",
  "modalEdit": false,
  "labelPosition": "top",
  "description": "",
  "errorLabel": "",
  "tooltip": "",
  "hideLabel": false,
  "tabindex": "",
  "disabled": false,
  "autofocus": false,
  "dbIndex": false,
  "customDefaultValue": "",
  "calculateValue": "",
  "calculateServer": false,
  "widget": {
    "type": "input"
  },
  "attributes": {},
  "validateOn": "change",
  "validate": {
    "required": false,
    "custom": "",
    "customPrivate": false,
    "strictDateValidation": false,
    "multiple": false,
    "unique": false,
    "minLength": "",
    "maxLength": "",
    "pattern": ""
  },
  "conditional": {
    "show": null,
    "when": null,
    "eq": ""
  },
  "overlay": {
    "style": "",
    "left": "",
    "top": "",
    "width": "",
    "height": ""
  },
  "allowCalculateOverride": false,
  "encrypted": false,
  "showCharCount": false,
  "showWordCount": false,
  "properties": {},
  "allowMultipleMasks": false,
  "mask": false,
  "inputType": "text",
  "inputFormat": "plain",
  "inputMask": "",
  "spellcheck": true,
  "id": "e2x5qwg"
}

属于可配置类型,这也是为什么在上文也标出了可以使用 formio 的部分功能。顺便,纯粹的前端 UI 部分是开源的。

总结

使用 formio 的方式不同,也各有利弊。

以全家桶来说,是一个封装已经完成的平台,它的封装相对而言比较完善,这也代表着使用的灵活度相对而言会低一些。上面的例子已经展示了怎样将表单渲染到页面上,整体的流程都是比较简单的,唯一需要做好规划的就是,当数据量比较大的时候,应该怎么样合理地对数据进行管理?

完全依赖于平台去做数据管理是一个相对而言比较浪费时间的事情。也因此,刚开始纯粹的依靠 formio 的平台进行开发的话,在后期可能会遭遇一些挑战。


【本文正在参与 “100%有奖 | 我的 Serverless 实战”征稿活动】

活动链接:https://marketing.csdn.net/p/15940c87f66c68188cfe5228cf4a0c3f

Logo

前往低代码交流专区

更多推荐