组件的名称统一大写,以大驼峰命名,和 Antd组件保持一致
import React, { useState, useRef } from 'react';import PropTypes from 'prop-types';import { Button, Drawer } from 'antd';import { CreateSuccess } from '@constants/message'import { FormBuild } from '@components/Form'import { formData } from './_formData';function App() {function onSubmit() {const form = formRef.current;}function buttonClick() {CreateSuccess()}return (<FormBuildcol={24}dataSource={formData(buttonClick)}ref={formRef}onSubmit={onSubmit}/>)}
FormBuild
FormBuild/index.js
import React from 'react';import PropTypes from 'prop-types';import classnames from 'classnames';import { Row, Col, Form, Button, Tooltip, Icon } from 'antd';import FormConfig from './FormConfig';const itemLayout = {labelCol: { span: 6 }, wrapperCol: { span: 18 },};FormBuild.propTypes = {dataSource: PropTypes.array.isRequired,onSubmit: PropTypes.func,action: PropTypes.bool,};FormBuild.defaultProps = {onSubmit: () => {},action: false,};function FormBuild(props) {const {form, dataSource,className, action,layout = {}, col: colWidth = 8,} = props;if (!dataSource.length) return null;const { getFieldDecorator } = form;// 表单样式const formClass = classnames({mb16: true,[className]: Boolean(className)});// 表单布局const formLayout = { ...itemLayout, ...layout };const handleSubmit = (ev) => {ev.preventDefault();// const values = form.getFieldsValue();form.validateFieldsAndScroll((err, values) => {if(err) return;onSubmit(values);// onReset();});};function onReset() {form.resetFields();};return (<Form{...formLayout}className={formClass}onSubmit={handleSubmit}><Row gutter={16}>{dataSource.map(item => {// 解构掉不需要传递给表单组件的参数const {label, name, colon = true, extra, rules, col = colWidth,valuePropName = 'value', value, noStyle, ...args} = item;const COMPONENT = <FormConfig {...args} />;return (<Col span={col} key={name}><Form.Itemlabel={label}extra={extra}colon={colon}>{noStyle? COMPONENT: getFieldDecorator(name, {initialValue: value,rules,valuePropName,})(COMPONENT)}</Form.Item></Col>);})}</Row>{action && (<Col span={24}><Button className='mr8' type='primary' htmlType='submit'>查询</Button><Button onClick={onReset}>重置</Button></Col>)}</Form>);}export default Form.create()(FormBuild);
label表单提示

修改 Form.Item的 label为 jsx
用不到这个功能,就不用替换,不用搞得太复杂
function LabelHelp({label, help}) {if(!help) return label;return (<span>{label} <Tooltip title={help}><Icon type='question-circle-o' /></Tooltip></span>)}// 修改为<Col span={col} key={name}><Form.Item label={<LabelHelp label={label} help={help} />}>// ...</Form.Item></Col>
Form.Item
<Form.Itemlabel={<span>Nickname <Tooltip title="What do you want others to call you?"><Icon type="question-circle-o" /></Tooltip></span>}>{getFieldDecorator('nickname', {rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }],})(<Input />)}</Form.Item>
FormConfig.js
FormBuild/FormConfig.js
初始化表单相关的组件,通过 props给表单添加属性
- 表单为受控组件,通过 antd的 Form,自动获取值
- value & onChange ```jsx import React from ‘react’; import { Input, InputNumber, Radio, DatePicker, Switch, AutoComplete, Button, } from ‘antd’;
import SelectArray from ‘@components/Select/SelectArray’;
const { TextArea, Password } = Input; const { RangePicker } = DatePicker;
const COMPONENT = { Input, Password, TextArea, InputNumber, Select: SelectArray, RadioGroup: Radio.Group, Switch, DatePicker, RangePicker, AutoComplete, Button, };
function FormConfig({ component, children, …props }) { const Component = COMPONENT[component]; if (!Component) return null;
return
export default FormConfig;
<a name="mJ8hY"></a>## formData.js```jsxexport const dataSource = [{ label: '基金', value: 'fund' },{ label: '黄金', value: 'gold' },];// 函数返回一个数组export function formData({type, buttonClick}) {return [{label: '类型',component: 'Select',name: 'type',value: type,rules: [{ required: true, message: '请选择数据源类型' },],help: '必填项',dataSource,},{label: '名称',component: 'Input',name: 'name',value: '',rules: [{ required: true, message: '请输入名称' },],},{label: '描述',component: 'TextArea',name: 'desc',value: '',extra: '描述最大长度200个字符',},{label: ' ',children: '测试配置',component: 'Button',type: 'dashed',colon: false,onClick: buttonClick,noStyle: true,},{label: '开关',component: 'Switch',name: 'lock',value: true,valuePropName: 'checked',checkedChildren: '是',unCheckedChildren: '否',},]}
回显表单值
form.setFieldsValue
useEffect(() => {const values = dataSource.reduce((prev, next) => {const {name, value} = next;prev[name] = valuereturn prev;}, {});form.setFieldsValue(values);}, [dataSource]);
