The following is the final presentation:



The version of ANTD uses the version of 3.x. Please modify the corresponding code according to the version

The code:

import React from "react"; import { Input, Form, Button, Icon} from "antd"; import styles from '.. /index.scss' const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 18 } }; let id = 0; class K8S extends React.Component { componentDidMount() { const {data, form} = this.props; this.props.onRef && this.props.onRef(this); // initialize id = 0; // Assign form.setFieldsValue({'namespace': data.namespace}); } // New namespace add = (k) => {const {form} = this.props; let keys = form.getFieldValue('keys'); Keys. Splice (indexOf(keys,k) + 1, 0, id++); Keys. Splice (indexOf(keys,k) + 1, 0, id++); form.setFieldsValue({ keys: keys, }); }; Const {form} = this.props; const keys = form.getFieldValue('keys'); if (keys.length === 1) { return; } form.setFieldsValue({ keys: keys.filter(key => key ! == k), }); }; GetInitialKeys (){const {data} = this.props; let nextKeys = []; for(let i = 0; i < data.namespace.length; i ++){ nextKeys.push(i) id++; } return nextKeys; } // form form data getFields() {const {getFieldDecorator, getFieldValue} = this.props. const { data } = this.props; const formItemLayoutWithOutLabel = { wrapperCol: { xs: { span: 24, offset: 0 }, sm: { span: 20, offset: 4 }, }, }; If (data.namespace) {getFieldDecorator(' Keys ', {' InitialValue ': this.getInitialKeys()}); } else { getFieldDecorator('keys', {'initialValue': [0]}); id++; } const keys = getFieldValue('keys'); const formItems = keys.map((k, index) => ( <Form.Item style={{position: 'relative'}} {... (index === 0 ? formItemLayout : formItemLayoutWithOutLabel)} label={index === 0 ? 'namespace' : ''} required={true} key={k} > {getFieldDecorator(`namespace[${k}]`, { validateTrigger: ['onChange', 'onBlur'], rules: [ { required: true, whitespace: true, message: <Input placeholder=" namespace" style={{width: 0; '450px'}} />)} <Icon className={styles.dynamicAddButton} type="plus-circle" onClick={() => this.add(k)}/> {keys.length > 1? (<Icon className={styles.dynamicDeleteButton} type="minus-circle-o" onClick={() => this.remove(k)}/>) : null} </Form.Item> )); return ( <> {formItems} <Form.Item {... formItemLayoutWithOutLabel}></Form.Item> </> ) } handleSubmit = (e) => { e && e.preventDefault && e.preventDefault(); this.props.form.validateFields((err, values) => { if (! err) { console.log(values) this.props.onSubmit(values); } }) } render() { return ( <div className={styles.k8s}> <Form onSubmit={this.handleSubmit} {... formItemLayout} > {this.getFields()} <div style={{ height: '32px' }}> <div style={{float: 'right'}}> <Button type="primary" htmlType="submit" </Button> </div> </div> </Form> </div>)} const K8SDetail = Form.create()(K8S); export default K8SDetail;

CSS Style Modification

.k8s{ :global{ .anticon-minus-circle-o, .anticon-plus-circle { cursor: pointer; position: absolute; top: -1px; right: -65px; font-size: 24px; color: #999; The transition: all 0.3 s; } .anticon-plus-circle{ right: -30px; } .anticon-minus-circle-o:hover,.anticon-plus-circle:hover { color: #777; } .anticon-minus-circle-o[disabled],.anticon-plus-circle[disabled] { cursor: not-allowed; Opacity: 0.5; } .ant-form-item-control{ width: 450px; float: right; }}}

This completes the above requirements, showing an empty input by default in Edit and Add modes. Insert and delete according to location. Note: There is a small bug left over. Each new ID increment increases by +2, because it does not affect usage and is not checked carefully