在使用antd form做动态表单开发时,官网有如下示例:
当添加表单项后:
使用此示例可以实现动态增加、减少表单项的功能,但是当我们编辑以前添加过的form表单时,该如何赋初值,又如何支持新增和编辑使用同一组件,即可以支持没有初值和有初值两种情况。本文分享了一种解决该问题的组件封装方式。
组件使用方式:
(this.tagRef = ref)}
/>
tag数据格式:
[{tagLabel:'label1',tagValue:'value1'}, {tagLabel:'label2',tagValue:'value2'}]
组件代码:
import React, {Component} from 'react';
import autobind from 'class-autobind';
import {Form, Input, Row, Col, Tooltip} from 'antd';
import './index.less';
const FormItem = Form.Item;
const prefixCls = 'tag-component';
class TagComponent extends Component{
constructor(props){
super(props);
this.state = {};
autobind(this, TagComponent.prototype);
this.formItemHasLabel = {
'labelCol': {'span': 12},
'wrapperCol': {'span': 12}
};
this.formItemHasLabelPosition = {
'labelCol': {'span': 0},
'wrapperCol': {'span': 12, 'offset': 12}
};
this.formItemNoLabel = {
'labelCol': {'span': 2},
'wrapperCol': {'span': 18}
};
this.uuid = 0;
}
componentDidMount(){ // DidMount赋初值
const {tag, form} = this.props;
let formTag = [];
for(let i = 0; i < tag.length; i ++){
formTag = formTag.concat([tag[i].tagLabel, tag[i].tagValue]);
}
form.setFieldsValue({
'formTag': formTag
});
}
getInitialKeys(){
const {tag} = this.props;
let nextKeys = [];
for(let i = 0; i < tag.length; i ++){
nextKeys = nextKeys.concat([this.uuid, this.uuid + 1]);
this.uuid = this.uuid + 2;
}
return nextKeys;
}
addTag(){
const {form} = this.props;
const keys = form.getFieldValue('keys');
const nextKeys = keys.concat([this.uuid, this.uuid + 1]);
this.uuid = this.uuid + 2;
form.setFieldsValue({
'keys': nextKeys
});
}
removeTag(index){
const {form} = this.props;
// can use data-binding to get
const keys = form.getFieldValue('keys');
// We need at least one passenger
if (keys.length === 0) {
return;
}
// can use data-binding to set
keys.splice(index - 1, 2);
form.setFieldsValue({
'keys': keys
});
}
renderTagFormItems(){
const {label} = this.props;
const {getFieldDecorator, getFieldValue} = this.props.form;
const initKeys = getFieldValue('keys');
const InitialKeys = initKeys || this.getInitialKeys();
getFieldDecorator('keys', {'initialValue': InitialKeys});
const formItemHasLabel = this.formItemHasLabel;
const formItemNoLabel = this.formItemNoLabel;
const formItemHasLabelPosition = this.formItemHasLabelPosition;
const keys = getFieldValue('keys');
const formItems = keys.map((k, index) => (
{getFieldDecorator(`formTag[${k}]`, {
'validateTrigger': ['onChange', 'onBlur'],
'rules': index % 2 === 0 ? [{
'required': true,
'whitespace': true,
'message': '必填,支持字母、数字、"."、"_"、"-",且不超过50字符',
'pattern': /^[A-Za-z0-9_\.-]{0,50}$/g
}] : [{
'required': true,
'whitespace': true,
'message':
'必填,支持字母、数字、"."、"_"、"-",且不超过50字符',
'max': 200
}]
})(
)}
{keys.length > 0 && index % 2 === 1 ? (
this.removeTag(index)} />
) : null}
)
);
return formItems;
}
render(){
const {getFieldValue} = this.props.form;
const keys = getFieldValue('keys');
const {label} = this.props;
const formItemLayout = keys && keys.length !== 0 ? this.formItemHasLabelPosition : this.formItemHasLabel;
return(
);
}
}
export default Form.create()(TagComponent);
样式文件index.less
.tag-component{
&-add{
&-box{
text-align: left;
}
&-btn{
color: #0058ff;
cursor: pointer;
width: 100%;
text-align: left;
&-text{
vertical-align: middle;
}
}
}
&-icon{
vertical-align: middle;
padding: 0 6px;
}
&-remove-btn{
cursor: pointer;
position: relative;
transition: all .3s;
margin-left: 4px;
}
&-input-left{
width: 100%;
}
&-input-right{
width: calc(~'100% - 20px');
}
}
效果如下:
初始状态、无初始值或初始值为[]:
添加表单项后:
添加值或编辑(有初始值):
对于组件的解释及用法请看下篇文件《使用antd form开发支持动态增减表单项,可选有初始值组件的一种实现方式(二)》。
地址:https://blog.csdn.net/smk108/article/details/84554386
demo地址:https://blog.csdn.net/smk108/article/details/101784236