以下为最终展示样式:
image.png
antd的版本用的是3.X的版本,各位根据版本修改对应的代码
上代码:

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);
        // 初始化id
        id = 0; 
        // 赋值 
        form.setFieldsValue({'namespace': data.namespace}); }

    // 新增namespace
    add = (k) => {
        const { form } = this.props;
        let keys = form.getFieldValue('keys');
        // 这里根据点击的下标进行插入操作
        keys.splice(indexOf(keys,k) + 1, 0, id++);
        form.setFieldsValue({
            keys: keys,
        });
     };

    // 移除namespace
    remove = k => {
        const { form } = this.props;
        const keys = form.getFieldValue('keys');
        if (keys.length === 1) {
            return;
        }
        form.setFieldsValue({
            keys: keys.filter(key => key !== k),
        });
    };
    
    // 初始化获取key
    getInitialKeys(){
        const {data} = this.props;
        let nextKeys = [];
        for(let i = 0; i < data.namespace.length; i ++){
            nextKeys.push(i)
            id++;
        }
        return nextKeys;
    }
    
    // form表单数据
    getFields() {
        const { getFieldDecorator, getFieldValue} = this.props.form;
        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: "请输入namespace",
                        },
                    ],
                })(<Input placeholder="请输入namespace" style={{width: '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样式修改

.k8s{
    :global{
        .anticon-minus-circle-o, .anticon-plus-circle {
            cursor: pointer;
            position: absolute;
            top: -1px;
            right: -65px;
            font-size: 24px;
            color: #999;
            transition: all 0.3s;
        }
        .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;
        }
    }
}

这样就完成了以上的需求,按照可进行编辑和新增两种模式,默认显示一个空的输入。可根据位置插入和删除。
注意:有个小bug残留,每次id新增都会以+2的状态递增,因为不影响使用也没仔细排查


柴门闻犬吠
32 声望2 粉丝

敬所有悬而未决的人生