实现Ant Design 自定义表单组件

来源:互联网 发布:mt4软件使用 编辑:程序博客网 时间:2024/06/04 19:36

  Ant Design 组件提供了InputInputNumberRadioSelectuplod等表单组件,但实际开发中这是不能满足需求,同时我们希望可以继续使用Form提供的验证和提示等方法(使用起来确实很爽),这时需要自己动手封装一些表单,同时我们还要保持方法可以继续是使用。

  组件的源码    https://github.com/haozhaohang/ant-design-expand-component

 

  下面看一下如何自己封装表单组件,这是一个最基础的表单使用例子:

import React, { PureComponent } from 'react'import { Button, Form, Input, Radio } from 'antd'import FormItem from 'components/FormItem'const RadioGroup = Radio.Groupconst options = [    { label: '男', value: 1 },    { label: '女', value: 2 },]class Test extends PureComponent {    handleSubmit = (e) => {        e.preventDefault();        const { form: { validateFields } } = this.props;        validateFields((errors, values) => {            if (errors) {                return;            }            console.log(values)        })    }    render() {        const { form: { getFieldDecorator } } = this.props        const nameDecorator = getFieldDecorator('name')        const sexDecorator = getFieldDecorator('sex')        return (            <section>                <Form layout="horizontal" onSubmit={this.handleSubmit}>                    <FormItem label="姓名">                        {nameDecorator(<Input />)}                    </FormItem>                    <FormItem label="年龄">                        {sexDecorator(<RadioGroup options={options} />)}                    </FormItem>                    <FormItem buttonsContainer>                        <Button type="primary" size="default" htmlType="submit">提交</Button>                    </FormItem>                </Form>            </section>        );    }}export default Form.create()(Test)


现在需求需要我们实现多个姓名的提交,这时使用UI组件提供的表单便无法实现。

  下面我们可以封装一个InputArrary组件:

import React, { PureComponent } from 'react'import PropTypes from 'prop-types'import { Button, Icon, Input } from 'antd'import './index.scss'class InputArray extends PureComponent {    constructor(props) {        super(props)    }    handleChange = index => {        const { value, onChange } = this.props        const newValue = [...value]        newValue[index] = target.value        onChange(newValue)    }    handleDelete = e => {        const target = e.currentTarget        const index = target.parentNode.parentNode.firstChild.dataset.index        const { value, onChange } = this.props        const newValue = [...value]        newValue.splice(Number(index), 1)        onChange(newValue)    }    handleAdd = () => {        const { value, onChange } = this.props        const newValue = [...value, '']        onChange(newValue)    }    render() {        const { value, ...others } = this.props        const closeBtn = <Icon type="close-circle" onClick={this.handleDelete} />        return (            <div className="input-array-component">                {value.map((v, i) => {                    return (                        <div key={i}>                            <Input                                {...others}                                value={v}                                suffix={closeBtn}                                data-index={i}                                onChange={() => this.handleChange(i)}                            />                        </div>                    );                })}                <div>                    <Button type="dashed" icon="plus" onClick={this.handleAdd}>添加</Button>                </div>            </div>        );    }}InputArray.defaultProps = {    value: []}export default InputArray


这是我们就可以像引入Input组件一样引入InputArray组件实现了一组姓名的提交。

<FormItem label="姓名">        {nameDecorator(<InputArray />)}</FormItem

  组件主要使用的form提供getFieldDecorator方法,这个方法会向组件注入value参数,onChange方法,每次调用onChange方法都会去改变value,从而刷新整个组件。为什么会这样那,其实Ant Design 会在表单组件外层包裹一层组件,维护一个State值,每次onChange都是在改变外部state值,调用setState来刷新表单组件。

  

  Upload组件使用中也遇到一个坑,Upload组件action上传地址参数也是必填参数,每次上传都会直接上传到服务器,不能和其它表单的数据一起提交,这时候我们也必须从新封装一个上传组件,同时因为存在文件或图片数据就不能使用json格式和后台进行交互,必须使用new FormData()的数据格式上传,也就是原生的表单的submit提交。

 

  组件的源码    https://github.com/haozhaohang/ant-design-expand-component


原创粉丝点击