JSON生成Form表单的方法示例(3)

JOSN表单只提供了input、select、textarea三种默认的表单组件,远远不够真实的项目中使用,所以我们可以将antd组件库中的组件封装到JSON表单中,这样我们就可以再项目中很快的使用antd中的组件。

antd-components.js

import React from 'react' import { Input } from 'antd' export default [ { type: 'antd-input', render: (curData, config, {changeFn, getFocus, loseFocus, error}) => { return <Input value={curData} onFocus={getFocus} onBlur={loseFocus} placeholder={config.placeholder ? config.placeholder : ''} style={{borderColor: !!error ? '#f5222d' : ''}} onChange={event => changeFn(event.target.value)} /> } } ]

我们在antd-components.js文件中声明一个antd-input的自定义组件,然后在JSON表单中引入该自定义表单组件:

init.js

import Form from 'Form' import components from './antd-components' From.createCustomComp(components) const config = { formKey: 'paramAddFromAntd', data: { name: '', }, config: [ { type: 'antd-input', dataKey: 'name', label: 'Param', placeholder: '请输入param', validate: ['required', /^[a-zA-Z_{}0-9]+$/g] } ] } <From ref={ref => this.FormWrap = ref} config={config}></From>

使用container来引入antd组件库,其原理就是通过container将antd组件封装成'antd-input'自定义组件,然后使用它,这种方式不仅可以用来封装组件库,还可以用来共享一些共用表单组件,可以将常用的复杂表单组件封装在一个共用文件里,然后在不同项目中引用,就可以跨项目共用表单组件。

在自定义组件中,如果需要自定义表单提交数据函数,但是又不能重写render方法以防覆盖原先的render方法,所以可以使用modifyDataFn方法来覆盖render中的提交数据部分。

modifyDataFn: ({changeFn, changeDataFn}, {parent, self}) => { let {parentData} = parent parentData = parentData.map(item => ({ ...item, name: self.curData })) changeDataFn(parent.parentKey, parentData) }

处理控制逻辑和联动逻辑

在JSON表单JSON配置中,有assistData的选填字段,该字段为JSON表单处理控制逻辑的额外数据,例如在表单内有一个刷新按钮,其实现代码如下:

{ data: {}, assistData: { refreshParam: false }, config: [ { type: 'container', dataKey: 'assistData.refreshParam', render: (curData, config, {changeFn, changeDataFn}) => { const handleClick = () => { changeDataFn('assistData.refreshParam' ,true) setTimeout(() => { changeDataFn('assistData.refreshParam' ,false) }, 1000 * 3) } return <React.Fragment> { config.index === config.parentData.length - 1 && <Popover placement="top" content="刷新param列表"> <Button shape="circle" loading={curData} onClick={handleClick}>{!curData && <Icon type="reload" />}</Button> </Popover> } </React.Fragment> } }, ] }

注意: 如果要使用assistData中的数据,其dataKey必须以assistData开头,且必须使用changeDataFn自定义提交assistData数据。

render方法内嵌套组件配置

{ type: 'container', dataKey: 'param', render: (curData, config, {changeFn, changeDataFn, JSONForm}) => { return <div> { JSONForm([ { type: 'input', dataKey: 'name', placeholder: '请输入param', validate: ['required'], } ]) } </div> }

这样就可以在container内嵌套组件配置,实现更复杂的表单组件。

JSON表单提交数据

非实时表单提交

非实时表单提交数据,就是在表单输入完毕后,点击提交按钮统一提交所有的数据,其提交的方式如下:

function handleClick() { this.FormRefs.getValue((valid, data) => { // valid 表示校验结果,false表示校验不通过 }) }

实时表单提交

实时表单的提交首先需要注册提交函数:

componentDidMount(){ this.FormRefs.registerSubmit((valid, data) => { console.log(valid, data) }) }

接着在配置里设置允许实时提交的字段:

{ formKey: '', realTimeSubmit: true }

如果需要在某些表单组件里自定义是否实时提交,需要在组件配置里设置阻止实时提交字段为true:

{ dataKey: '', preventSubmit: true }

JSON表单的应用场景

表单分类

a. 按复杂度分类
1. 简单表单:表单组件为input、select、textarea等常见的几种,且表单组件之间逻辑独立
2. 复杂表单:表单组件内容和交互复杂且相互之间存在复杂的逻辑

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/7747ee195028a32af5715989b379d953.html