阅读 4170

中后台Form表单工具 EasySchemaForm 开源了

Git: github.com/hellosean10…

背景

后台系统往往有大量的 form 表单需要开发,传统的开发方式比如用 antd ,效率是非常低下的,举个 Antd 例子:

传统方式开发:

代码里面混合了各类组件(布局、逻辑、验证规则、表单元素等)和 javascript 代码逻辑,所以我们思考有没有更好的解决方案,比如能不能用如下的一段 JSON 配置出来:


{
    "name": {
       type:"string",
       title: "名称"
    },
    "email": {
       type: "string",
       title: ""
    }
}

复制代码

经过调研, react-json-schema-form 比较符合我们的需求,能够基于标准的 JSON-SCHEMA 生成所需要的 form 表单,满足表单校验和数据描述,非常简单实用。

{
  "title": "A registration form",
  "description": "A simple form example.",
  "type": "object",
  "required": [
    "firstName",
    "lastName"
  ],
  "properties": {
    "firstName": {
      "type": "string",
      "title": "First name"
    },
    "lastName": {
      "type": "string",
      "title": "Last name"
    }
  }
}
复制代码

但同时使用 react-json-schema-form 存在着以下问题:

  1. 从基础交互来说,react-json-schema-form 使用 Bootstrap 这一套来做的 UI,目前我们这边系统大量使用了 Antd 库,不匹配;
  2. 复杂的表单交互不易用,比如我们这边有些 array 结构的 form 表单,有大量的数据条数(在50条左右),react-json-schema-form 交互使用了每个字段占用一行的设计,也就是说如果有6个字段,共50条数据,需要占用 300行空间;
  3. 不支持通过 js 表达式 ;
  4. uiSchema 和 json-schema 分开,导致在遇到深层级节点时不好配,还有节点有改动,需要同步 uiSchema。

基于以上这些原因,我们考虑了自研一套 schema 解决方案。

目标

  1. 采用标准化交互,满足各类需求
    • 为了实现这个目的,我们对 object 类型统一为左右两栏布局;
    • 对 Object[] 类型,采用了表格式布局,可以设置不常用编辑项或一些比较占用空间的编辑项通过弹层的方式打开编辑;
  2. 支持对Object 类型字段分类,使用 Tab 布局
  3. 使用了 ajv 验证库
  4. 支持通过 js 表达式实现联动交互(比如隐藏、禁用等)
  5. 支持自定义组件

基于以上的目标,技术方案如图所示:

相比 react-json-schema-form 优势

schema.gif

  1. 支持联动;
  2. 轻松支持数组类型的 form 表单,并对比较占用视图的元素做了弹层的处理,交互更为易用,轻松支持上百条数组表单数据;
  3. 支持无限嵌套;

更多示例可参考 PlayGround

Install

npm i easy-schema-form
复制代码

Usage

import EasyForm from 'easy-schema-form'
import 'easy-schema-form/dist/main.css'


const schema = {
  type: "object",
  required: ['name'],
  properties: {
    name: {
      title: '用户名',
      type: "string",
      description: "zzzzzz",
      pattern: "[0-9]+"
    },
  }
}

export default class App extends React.PureComponent {
  static propTypes = {
    curTab: Proptypes.string.isRequired,
    match: Proptypes.object,
  };
  state = {
    data: {}
  };

  onChange =(value)=>{
    this.setState({
      data: value
    })
  }

  render () {
    return (
      <EasyForm onChange={this.onChange} value={this.state.data} schema={schema} />
    );
  }
}

复制代码

License

MIT

贡献:

Git: github.com/hellosean10…

文章分类
前端
文章标签