1.0.1 • Published 6 months ago

rice-drip-form v1.0.1

Weekly downloads
-
License
ISC
Repository
-
Last release
6 months ago

drip-form

简介

drip-form 是一个自动表单渲染平台,支持以 JSON Schema 数据结构数据自动渲染表单内容。用一个方案去解决表单的复杂性、联动性、多样性、可配置、性能、ui 框架自由。

本项目能帮助你解决如下问题

  1. 只需提供 JSON Schema 数据结构数据即可自动渲染出所需要的表单
  2. 多表单联动
  3. 可配置表单顺序、兜底文案、错误类型等
  4. UI 框架自由,可选择两种主题(antd - 已支持、babel-ui-待支持)
  5. 提升性能,避免一次改动渲染整个表单
  6. 当表单过于复杂时,可为特定商家做到精简版

环境

node >=13.14.0

yarn >=1.0.0

安装

jnpm install @jdfed/drip-form

主题安装

jnpm install @jdfed/drip-form-theme-antd

引入

import BabelForm from '@jdfed/drip-form'
import antd from '@jdfed/drip-form-theme-antd'
import '@jdfed/drip-form/dist/drip-form.min.css'
import '@jdfed/drip-form-theme-antd/dist/drip-form-theme-antd.min.css'

drip-form 渲染流程

Image text

参数说明

Json-Schema 参数参数配置说明

dataSchema

dataSchema 为 drip-form 表单定义组件唯一 Key,提供校验等功能。

参数说明

如需渲染最基本的表单,dataSchema 必须配置项为$schemaproperties$schema赋予校验当前 JSON 能力,我们在properties中定义表单组件。

属性说明类型是否为必须项
\$schema指定当前校验用的 json-schema 协议规范。目前支持到draft-07stringtrue
title表单标题stringfalse
type表单的数据结构object、arrayfalse
validateTime执行校验的时间change(数据变化时)、submit(表单提交时)false
properties表单子项配置objecttrue
required表单中必填项配置,表单子项 key 值构成的数组arrayfalse
errorMessage错误提示配置objectfalse

一个简单的配置示例,这里我们定义两个组件的唯一 Key 值radio1select1title是该组件名称,type是该组件数据类型,default给组件设置默认值。

{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"properties": {
		"radio1": {
			"title": "单选框",
			"type": "boolean",
			"default": true
		},
		"select1": {
			"title": "选择器",
			"type": ["string", "number", "array"]
		}
	}
}

properties 表单子项配置

properties是 dataSchema 必填项,这里我们详细说明下。

属性说明类型
title组件名称,用于渲染 labelstring
type组件中使用的数据类型stringnumberarrayboolean
default组件默认值*
customFormat自定义校验规则 date-time、colorstring
rangeDelimiter限制范围object
*根据类型配置可选的校验规则,基于ajv-validationajv-keywords

properties中定义组件唯一 key 值,名称可以自定义。

这里定义了name2erpnumber1colorPicker,并且在erpnumber1中定义了 drip-form 提供的校验规则rangeDelimiter、以及 ajv 中的校验参数。

customFormat (drip-form 提供的校验规则)

customFormmat 提供date-timecolor校验

示例

{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"properties": {
		"datePicker": {
			"title": "datePicker",
			"type": "string",
			"customFormat": "date-time"
		},
		"colorpicker": {
			"type": "string",
			"title": "颜色选择器",
			"default": "#08c691",
			"customFormat": "color"
		}
	}
}

rangeDelimiter(限制范围)

对组件中的 string 类型进行校验,用分隔符校验长度。如校验输入的 ERP 账号。

参数说明类型是否为必传
delimiter定义分隔符,如逗号, 分号;stringtrue
max最大长度numbertrue
min最小长度numbertrue

示例

{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"properties": {
		"erp": {
			"title": "erp",
			"type": "string",
			"rangeDelimiter": {
				"delimiter": ",",
				"max": 2,
				"min": 0
			}
		}
	}
}

required 规定表单中必填项

如果需要在表单中规定必填项,就可以在这里规定需要校验的表单中的组件,required中填入在properties中定义的 key 值。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
	"type": "object",
	"validateTime": "change",
  "properties": {
    "text1": {
      ....
    },
    "text2": {
      ....
    }
  },
  "required": [
    "text1",
    "text2"
  ],
  "errorMessage": {
    "required": {
      "text1": "必填",
      "text2": "必填"
    },
    "properties": {
			"text1": "...",
			"text2": "..."
		}
  }
}

errorMessage 配置

错误信息配置是用来做表单校验提示,当表单中组件校验错误会在组件下方提示错误信息

属性说明类型
required必填项校验的报错信息,根据 key 值生成object
properties表单子项配置校验的报错信息,根据 key 值生成object

drip-form 提供校验(目前支持data-timecolorrangeDelimiter

示例

{
  "$schema": "http://json-schema.org/draft-07/schema#",
	"type": "object",
	"validateTime": "change",
  "properties": {
    "datePicker": {
			"title": "datePicker",
			"type": "string",
			"customFormat": "date-time"
		},
    "colorpicker": {
			"type": "string",
			"title": "颜色选择器",
			"default": "#08c691",
			"customFormat": "color"
		},
    "erp": {
			"title": "erp",
			"type": "string",
			"rangeDelimiter": {
				"delimiter": ",",
				"max": 2,
				"min": 0
			}
    }
	},
	"required": [
		"timepicker",
		"datePicker",
		"erp"
	],
	"errorMessage": {
		"required": {
			"datePicker": "必填",
			"colorpicker": "必填",
			"erp": "必填",
		},
		"properties": {
			"timepicker": "时间格式错误",
			"datePicker": "时间格式错误",
			"erp": "最多10个",
		}
	}
}

2.uiSchema (表单中各个组件类型及组件参数数据) 必传

  • order表单项顺序,默认按照 dataSchema 生成,只有在 order 里面的字段才会被渲染
  • theme是可选 UI 使用主题,现已支持 antd 组件主题
  • properties中配置表单中组件的类型及组件参数数据,type表示使用什么组件
{
    "order": ["formItem1"],
    "theme": "antd",
    "properties": {
        ...
    }
}
属性说明类型默认值
order表单项顺序,默认按照 dataSchema 生成。只有在 order 里面的字段才会被渲染array-
theme框架主题antdantd
properties表单子项配置object-

properties 表单子项配置

属性说明类型
type表单项类型text
disabled是否禁用boolean
vcontrol控制表单联动展示隐藏部分string
description表单提示object
style表单样式object
requestCache是否每次都调接口查询表单数据。需要配合 babelForm 的 onQuery 字段使用boolean 目前 select、cascader 支持
*根据类型配置可选的 UI 补充项*
{
	"order": ["babelRadio", "babelSelect"],
	"theme": "antd",
	"properties": {
		"babelRadio": {
			"type": "radio",
			"theme": "babel-ui",
			"options": [
				{ "label": "北京", "value": "0" },
				{ "label": "上海", "value": "1" },
				{ "label": "成都", "value": "2" },
				{ "label": "武汉", "value": "3" }
			]
		},
		"babelSelect": {
			"type": "select",
			"theme": "babel-ui",
			"options": [
				{ "label": "苹果", "value": "1", "disabled": false },
				{ "label": "橘子", "value": "2", "disabled": true },
				{ "label": "桃子", "value": "3", "disabled": false },
				{ "label": "香蕉", "value": "4", "disabled": false }
			]
		}
	}
}

说明

properties 中定义的是组件渲染项,通过 dataSchema 中定义的组件唯一 key 值进行渲染如下图对应关系

{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"properties": {
		"babelRadio": {
			"title": "单选框",
			"type": "string",
			"default": "0"
		},
		"babelSelect": {
			"title": "选择器",
			"type": ["string", "number", "array"],
			"default": []
		}
	}
}

properties 参数

属性说明类型
type表单项类型text
disabled是否禁用boolean
vcontrol控制表单联动展示隐藏部分string
description表单提示object
style表单样式object
requestCache是否每次都调接口查询表单数据。需要配合 babelForm 的 onQuery 字段使用boolean 目前 select、cascader 支持
*根据类型配置可选的 UI 补充项,根据 babel-ui 组件参数来定义 drip-form 中组件*

vcontrol

可以用来控制表单中其他组件的显隐

"vcontrol": "return formData.switch1"

formData是关键字

在需要被控制的组件中写入vcontrol,如使用switch组件对自定义组件custom1的显示隐藏进行控制。

🌰

dataSchema

{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"type": "object",
	"validateTime": "change",
	"properties": {
		"switch1": {
			"title": "开关",
			"type": "boolean"
		},
		"custom1": {
			"title": "自定义组件"
		}
	},
	"required": [],
	"errorMessage": {
		"required": {},
		"properties": {}
	}
}

uiSchema

{
  "order": ["switch1","custom1"],
  "theme": "babel-ui",
  "properties": {
    "switch1": {
			"type": "switch"
    },
    "custom1": {
			"type": "custom",
			"vcontrol": "return formData.switch1"
    }
  }
}

component

import React, { Component, memo, useState } from 'react'
import BabelForm from '@jdfed/drip-form'
import BabelUI from '@jdfed/drip-form-theme-babelUI'
import BabelUIComponent from '@jdfed/babel-ui'
import dataSchema from './dataSchema.json'
import uiSchema from './uiSchema.json'

import '@jdfed/drip-form/dist/drip-form.min.css'

const { Button } = BabelUIComponent

const CustomField1 = memo(() => {
	const [count, setCount] = useState(0)
	return (
		<div>
			<p>You clicked {count} times</p>
			<Button onClick={() => setCount(count + 1)}>Click me</Button>
		</div>
	)
})

const customComponents = {
	custom1: CustomField1,
}

export default class Form extends Component {
	render() {
		return (
			<div>
				<BabelForm
					dataSchema={dataSchema}
					uiSchema={uiSchema}
					uiComponents={{
						'babel-ui': BabelUI,
					}}
					customComponents={customComponents}
				/>
			</div>
		)
	}
}

uiComponents

选择的主题包,如选用 antd 主题

import antd from '@jdfed/drip-form-theme-antd'
import '@jdfed/drip-form-theme-antd/dist/drip-form-theme-antd.min.css'

control

做表单联动操作,对表单的 UI 进行渲染
如操作 Radio 组件

control = {({ dispatch, formData }) => {
          dispatch({
            type: 'setDataSchema',
            'properties.custom.title': formData.radio === '0' ? '0' : '1',
          })
        }}

onQuery

对于数据量较大的数据,可采用异步获取数据。

onQuery={treeSelect: async ({ isFirstLoad, pId }) => {
        //这里做些异步获取数据操作
        console.log('treeselect异步查询数据')
      }}

customComponents

自定义组件

const customComments = () => return <div>自定义组件</div>

表单数据获取

通过 ref.current 获取到表单的错误(errors)和表单的数据(formData)

const ref = useRef()
const onSubmit = () => {
  console.log(ref.current)
}
<BabelForm
    ref={ref}
    dataSchema={dataSchema}
    uiSchema={uiSchema}
/>
<Button
  type="primary"
  className="button--submit"
  onClick={() => {
    onSubmit()
  }}
>
  提交表单
</Button>

使用

示例 1

import BabelForm from '@jdfed/drip-form'
import antd from '@jdfed/drip-form-theme-antd'
import '@jdfed/drip-form-theme-antd/dist/drip-form-theme-antd.min.css'
import '@jdfed/drip-form/dist/drip-form.min.css'

const dataSchema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
	"type": "object",
	"validateTime": "change",
    "properties": {
      "number1": {
        "title": "年龄",
        "type": "number",
        "minimum": 0,
        "maximum": 100,
        "multipleOf": 3
		},
      "select1": {
        "title": "选择器",
        "type": ["string", "number", "array"],
        "default": []
        }
  }
}

const uiSchema = {
  "order": ["number1", "select1"],
      "theme": "antd",
      "properties": {
        "number1": {
			"type": "number",
			"placeholder": "请输入数字",
			"step": 10,
			"min": 0,
			"max": 100,
			"style": {
				"width": 110
			}
		},
		"select1": {
			"type": "select",
			"placeholder": "请选择",
			"allowClear": true,
			"multiple": true,
			"style": {
				"width": "100%"
			},
			"requestCache": true
		  }
  }
}

const Demo = () => (
  <>
    <BabelForm
      uiSchema={uiSchema}
      dataSchema={dataSchema}
      uiComponents={{ antd }}
    />
  </>
)

上述配置后渲染的实例

Image text

组件支持主题

  • 持续更新
组件名antd 主题babel-ui 主题
text 文本输入已支持已支持
number 数字输入已支持已支持
select 选择器已支持已支持
radio 单选框已支持已支持
null 空表单已支持已支持
switch 开关已支持已支持
slider 滑动输入条已支持待支持
timePicker 时间选择器已支持已支持
datePicker 日期选择器已支持待支持
colorPicker 颜色选择器已支持已支持
checkbox 多选框已支持已支持
uploader 上传已支持待支持
cascader 级联选择已支持已支持
treeSelect 树形选择器已支持待支持

drip-form API

参数类型是否为必传描述
dataSchemaobjecttrue表单中组件类型配置项
uiSchemaobjecttrue表单中各组件配置内容数据
uiComponentsobjecttrue主题(现支持 ant)
customComponents{custom: {}}false自定义组件
controlfunctionfalse表单联动,将当前表单数据传递到另外一个表单中
onQueryobjectfalse异步获取表单组件中的数据

示例 2

import BabelForm from '@jdfed/drip-form'
import antd from '@jdfed/drip-form-theme-antd'
mport '@jdfed/drip-form-theme-antd/dist/drip-form-theme-antd.min.css'
import '@jdfed/drip-form/dist/drip-form.min.css'

//表单中组件类型配置项
const uiSchema = {
  "order": [
    "timepicker",
    "datePicker",
    "colorpicker",
  ],
  "theme": "antd",
  "properties": {
    "timepicker": {
		"type": "timePicker",
		"range": true
	},
	"datePicker": {
		"type": "datePicker"
	},
	"colorpicker": {
		"type": "colorPicker"
	},
  }
}

//表单中各组件配置内容数据
const dataSchema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "validateTime": "change",
  "properties": {
    "timepicker": {
      "title": "timepicker",
      "type": "array",
      "items": [
        {
          "type": "string",
          "format": "time"
        },
        {
          "type": "string",
          "format": "time"
        }
      ]
    },
    "datePicker": {
      "title": "datePicker",
      "type": "string",
      "customFormat": "date-time"
    },
    "colorpicker": {
      "type": "string",
      "title": "颜色选择器",
      "default": "#08c691",
      "customFormat": "color"
    },
  },
  "required": [
    "timepicker",
    "datePicker",
    "colorpicker",
  ],
  "errorMessage": {
    "timepicker": "必填",
    "datePicker": "必填",
    "colorpicker": "必填",
  }
}


//自定义组件
const customComments = () => return <div>这是自定义组件,会随着单选框的值改变标题</div>

const App = () => {
  <>
    <BabelForm
      uiSchema={uiSchema}
      dataSchema={dataSchema}
      uiComponents={{uiComponents}}
      customComments={customComments}
      control={({ dispatch, formData }) => {
          dispatch({
            type: 'setDataSchema',
            'properties.custom.title': formData.radio === '0' ? '0' : '1',
          })
        }}
      onQuery={treeSelect: async ({ isFirstLoad, pId }) => {
        //这里做些异步获取数据操作
        console.log('treeselect异步查询数据')
      }}
    />
  </>
}

效果图

Image text Image text

混合主题

Babel-Form支持多主题混合样式,用户只需要针对uiSchema做相关配置修改,同时引入需要的主题包即可:

  • 修改uiSchema

    /* config.js */
    
    export const uiSchema = {
    	// 默认使用antd主题包
    	theme: 'antd',
    	// 其他配置项
    	properties: {
    		name: {
    			title: '名字',
    			// 针对该子项配置主题,使用babel-ui渲染
    			theme: 'babel-ui',
    			type: 'string',
    			maxLength: 5,
    			transform: ['trim'],
    		},
    	},
    }
  • 引入主题包

    /* App.js */
    
    ...
    // 除antd外,导入babel-ui主题包
    import BabelUI from '@jdfed/drip-form-theme-babelUI'
    
    // 导入多个主题包
    <BabelForm
      ...
      uiComponents={{
          antd,
          'babel-ui': BabelUI
      }}
     />