视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
实现AntDesign自定义表单组件实例详解
2020-11-27 20:19:16 责编:小采
文档


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

  组件的源码

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

 1 import React, { PureComponent } from 'react' 
 2 import { Button, Form, Input, Radio } from 'antd' 
 3 import FormItem from 'components/FormItem' 
 4 
 5 const RadioGroup = Radio.Group 
 6 const options = [ 
 7 { label: '男', value: 1 }, 
 8 { label: '女', value: 2 }, 
 9 ]
 10 
 11 class Test extends PureComponent {
 12 handleSubmit = (e) => {
 13 e.preventDefault();
 14 
 15 const { form: { validateFields } } = this.props;
 16 
 17 validateFields((errors, values) => {
 18 if (errors) {
 19 return;
 20 }
 21 console.log(values)
 22 })
 23 }
 24 
 25 render() {
 26 const { form: { getFieldDecorator } } = this.props
 27 
 28 const nameDecorator = getFieldDecorator('name')
 29 const sexDecorator = getFieldDecorator('sex')
 30 
 31 return (
 32 <section>
 33 <Form layout="horizontal" onSubmit={this.handleSubmit}>
 34 <FormItem label="姓名">
 35 {nameDecorator(<Input />)}
 36 </FormItem>
 37 
 38 <FormItem label="年龄">
 39 {sexDecorator(<RadioGroup options={options} />)}
 40 </FormItem>
 41 
 42 <FormItem buttonsContainer>
 43 <Button type="primary" size="default" htmlType="submit">提交</Button>
 44 </FormItem>
 45 </Form>
 46 </section>
 47 );
 48 }
 49 }
 50 
 51 export default Form.create()(Test)

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

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

 1 import React, { PureComponent } from 'react' 
 2 import PropTypes from 'prop-types' 
 3 import { Button, Icon, Input } from 'antd' 
 4 
 5 import './index.scss' 
 6 
 7 class InputArray extends PureComponent { 
 8 constructor(props) { 
 9 super(props)
 10 }
 11 
 12 handleChange = index => {
 13 const { value, onChange } = this.props
 14 const newValue = [...value]
 15 
 16 newValue[index] = target.value
 17 
 18 onChange(newValue)
 19 }
 20 
 21 handleDelete = e => {
 22 const target = e.currentTarget
 23 const index = target.parentNode.parentNode.firstChild.dataset.index
 24 const { value, onChange } = this.props
 25 const newValue = [...value]
 26 
 27 newValue.splice(Number(index), 1)
 28 
 29 onChange(newValue)
 30 }
 31 
 32 handleAdd = () => {
 33 const { value, onChange } = this.props
 34 const newValue = [...value, '']
 35 
 36 onChange(newValue)
 37 }
 38 
 39 render() {
 40 const { value, ...others } = this.props
 41 
 42 const closeBtn = <Icon type="close-circle" onClick={this.handleDelete} />
 43 
 44 return (
 45 <p className="input-array-component">
 46 {value.map((v, i) => {
 47 return (
 48 <p key={i}>
 49 <Input
 50 {...others}
 51 value={v}
 52 suffix={closeBtn}
 53 data-index={i}
 54 onChange={() => this.handleChange(i)}
 55 />
 56 </p>
 57 );
 58 })}
 59 <p>
 60 <Button type="dashed" icon="plus" onClick={this.handleAdd}>添加</Button>
 61 </p>
 62 </p>
 63 );
  }
 65 }
 66 
 67 InputArray.defaultProps = {
 68 value: []
 69 }
 70 
 71 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提交。

  组件的源码

  如果为你提供了一定的帮助,请点 start 支持一下

下载本文
显示全文
专题