组件的源码
下面看一下如何自己封装表单组件,这是一个最基础的表单使用例子:
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 ); 64 } 65 } 66 67 inputarray.defaultprops = { 68 value: [] 69 } 70 71 export default inputarray
这是我们就可以像引入input组件一样引入inputarray组件实现了一组姓名的提交。
<formitem label="姓名">{namedecorator(<inputarray />)} 组件主要使用的form提供getfielddecorator方法,这个方法会向组件注入value参数,onchange方法,每次调用onchange方法都会去改变value,从而刷新整个组件。为什么会这样那,其实ant design 会在表单组件外层包裹一层组件,维护一个state值,每次onchange都是在改变外部state值,调用setstate来刷新表单组件。
upload组件使用中也遇到一个坑,upload组件action上传地址参数也是必填参数,每次上传都会直接上传到服务器,不能和其它表单的数据一起提交,这时候我们也必须从新封装一个上传组件,同时因为存在文件或图片数据就不能使用json格式和后台进行交互,必须使用new formdata()的数据格式上传,也就是原生的表单的submit提交。
组件的源码
如果为你提供了一定的帮助,请点 start 支持一下
以上就是实现ant design自定义表单组件实例详解的详细内容。
