找回密码
 会员注册
查看: 176|回复: 0

配置化表单FormRender初尝试

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64021
发表于 2024-9-20 08:37:15 | 显示全部楼层 |阅读模式
相信常常做中后台项目的同学都知道,中后台50%的场景和表单有关,并在可灵活配置要求很高,特别是搭建表单配置场景,如果能通过下发JSON配置来生成表单视图的方法,理论上可以提高开发效率。然而,我找到了一个非常好用的表单插件,就是通过下发JSON配置来生成表单视图的方法!!!!它就是FormRender,一站式中后台表单解决方案它有什么优点?支持AntDesign和FusionDesign主流的视觉主题使用JSONSchema标准协议描述表单配置,并搭配丰富类型且可扩展的组件支持1排N、支持对象无限嵌套、自定义正则校验、自定义样式组件、列表拖拽等特性已在飞猪、亚博科技、安全智能、淘宝、新零售行业工作台、人工智能实验室、天猫等多场景使用,可支持复杂场景使用维护上有专人支持香不香?我反正已经上手使用过了,是真的香!遇到这种灵活多变的表单配置化需求,一个输入框和select都甚至需要封装成一个组件,写完一个组件,就要在components增加一个文件夹,要是用了这个插件,一些基础的组件可以直接用,要是不满足你的需求的话,也可以自定义组件(有这种类似场景的同学看过来,福利啊)再讲一下这个插件的缺点插件诞生也就两三年,可能会有一些bug,这是难免的文档不是很全待发现...但我目前用下来是没啥大问题的那么大家就会问呢?实际开发复杂度有多高?能支持复杂场景么?能支持联动么?能支持多样化的定制需求么?当然答案都是肯定的,接下来带大家体验一下设计方案协议层定义协议(schema)配置,展示层控制协议的渲染,工具层提供上下游的进一步支持。在此之上,FR遵循如下的api设计:基于JSONschema的协议规范。JSONschema作为JSON数据校验表述的国际标准,主要用于表单数据的服务端校验。已经接入JSONSchema标准的团队可以几乎无缝接入FR极简的组件api: FormRender使用上类似一个单独的可控的input:// 可控的input// form-render, 只多了schema,用于描述 Form 长什么样这样的设计下,FR只负责管理和改动表单数据/时时校验,而将具体如何使用表单数据和校验信息乃至提交的方式全权交给了使用者自由书写。支持复杂联动: schema的大部分属性都支持函数表达式,实现了灵活但强大的联动效果。更多示例见在线demo-复杂联动"showMore": {  "title": "显示更多",  "type": "boolean"},"input1": {  "title": "输入框1",  "type": "string",  "hidden": "{{rootValue.showMore === false}}" // 当showMore值为false时,隐藏}。支持个性化扩展:当出现现有表单元素无法满足需求的场景,FR使用自定义组件的方式,让用户自由扩展FR的组件库。备注:自定义组件就是普通的React组件,唯一的要求是要有value/onChange这两个props,用于双向绑定值。所以如果现成的组件已经默认使用了 value/onChange,就可以直接拿来用。// 写自定义组件const MyInput = ({ value, onChange }) => {  return  onChange(e.target.value)} />;};// 传入自定义组件;协议上只需指明"widget":"MyInput",即可使用对应的组件来渲染:text: {  title: "你好",  type: "string",  "widget": "myInput"}一句话总结,基于JSONschema的协议确保了FR的规范性,可控组件的模型确保了外层api的简洁和解耦,联动&自定义组件的api确保了对大量复杂的场景的很好支持。下面我来谈谈小伙伴们最关心的实际使用体感吧。使用体验&流程安装:FormRender依赖antdesign,单独使用不要忘记同时安装antdnpmiform-render--save最简demoimport React from 'react';import { Button } from 'antd';import FormRender, { useForm } from 'form-render';const schema = {  type: 'object',  properties: {    input1: {      title: '简单输入框',      type: 'string',      required: true,    },    select1: {      title: '单选',      type: 'string',      enum: ['a', 'b', 'c'],      enumNames: ['早', '中', '晚'],    },  },};const Demo = () => {  const form = useForm();  const onFinish = (formData, errors) => {    console.log('formData:', formData, 'errors', errors);  };  return (                        提交            );};export default Demo;从demo中我们不难发现FormRender的一些设计:以schema来描述表单展示,提交方式与antdv4的方式类似。schema以国际标准的JSONschema为基础,同时能够方便使用任何antd的props。通过bind字段,我们允许数据的双向绑定,数据展示和真实提交的数据可以根据开发需求不同(例如从服务端接口拿到不规则数据时,也能直接使用)。使用{{...}}书写表达式来完成简单的联动,值得一提的是,这里表达式支持所有js语法。FR还提供自定义组件、dependencies声明、watch等工具用于更加复杂的定制。可以通过displayType,labelWidth等字段轻易修改展示。通过使用schema编辑器,生成一个表单的流程非常简单,有兴趣的同学可以按下面示例在线尝试一下,体会它的强大性:使用在线schema编辑器搭建表单,导出schema将schema作为props传入组件在线(demo中替换schema.json文件内容即可)在原有的基础组件支撑下,我们需要一个复杂联动的自定义组件,如图当时在封装这个自定义组件时遇到的一个小坑:如上图标注,组件只挂载了一次,导致给自定义组件传的recycleLinkCode,刚开始拿到的初始值是空,但是组件已经挂载完了,等到接口返回recycleLinkCode的值时,传过去的数据没有实时更新。官方给出的理由是:formData的更新才会触发表单的重新渲染,但是recycleLinkCode不是表单值,所以不能用form.setValues和form.setValueByPath来修改表单值解决办法:接口拿到数据之后再去加载组件;触发组件重新渲染,可以试试这样写:useMemo(()=>,[recycleLinkCode])。写在最后总体来说这个插件已经很nice了,可以满足一般表单基本的需求。使用拖拽形式,也完全可以交给产品运营同学直接进行表单配置组合。一些资源链接github:github.com/alibaba/x-render官网:alibaba.github.io/x-render/codeSandbox:codesandbox.io/s/form-renderjichudemo-8k1l5使用场景:github.com/alibaba/x-render/issues/94schema编辑器:alibaba.github.io/x-render/generator
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 00:55 , Processed in 0.411894 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表