美文网首页
antdv4动态表单

antdv4动态表单

作者: 大佬啊 | 来源:发表于2020-03-15 21:14 被阅读0次

    V3的时候做过相关的表单,参照官方文档,但是当时是通过数值及数组控制相关的展示,在getDerivedStateFromProps中判断返显及修改值时非常麻烦,新版本的V4就简单很多了,示例图如下:


    微信截图_20200315210946.png

    一、引入对应的动态表单组件

    import React from 'react';
    import { Form, Button } from 'antd';
    
    
    import DymicForm  from './Dymic';
    
    const formItemLayoutWithOutLabel = {
     wrapperCol: {
       xs: { span: 24, offset: 0 },
       sm: { span: 20, offset: 4 },
     },
    };
    
    const DynamicFieldSet = () => {
     const onFinish = values => {
       console.log('Received values of form:', values);
     };
    
     return (
       <Form
         name='dynamic_form_item'
         { ...formItemLayoutWithOutLabel }
         initialValues={ {
           names: [
             {
               key: '147.118.114',
               value: 'www.xxx.com',
             },
             {
               key: '133,144,233',
               value: 'www.fff.com',
             },
           ],
         } }
         onFinish={ onFinish }>
         <DymicForm
           label='网关'
           name='names'
           placeholders={ ['请输入相关IP!', '请输入对应域名!'] } />
         <Form.Item>
           <Button htmlType='submit' type='primary'>
             提交
           </Button>
         </Form.Item>
       </Form>
     );
    };
    
    export default DynamicFieldSet;
    

    二、DymicForm组件

    import React from 'react';
    import { Form } from 'antd';
    import PropTypes from 'prop-types';
    import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
    
    
    import PriceInput  from './inpux';
    
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 4 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 20 },
      },
    };
    const formItemLayoutWithOutLabel = {
      wrapperCol: {
        xs: { span: 24, offset: 0 },
        sm: { span: 20, offset: 4 },
      },
    };
    
    const DynamicFieldSet = ({ name, label, placeholders }) => {
      return (
        <Form.List name={ name }>
          {(fields, { add, remove }) => {
            return (
              <div>
                {fields.map((field, index) => (
                  <Form.Item
                    { ...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel) }
                    key={ field.key }
                    label={ index === 0 ? label : '' }
                    required={ false }>
                    <Form.Item
                      { ...field }
                      noStyle
                      rules={ [
                        {
                          validator: async(rule, value) => {
                            if (value.key === undefined || value.value === undefined || value.key === '' || value.value === '') {
                              throw new Error('请填写完整!');
                            }
                          },
                        },
                      ] }
                      validateTrigger={ ['onChange', 'onBlur'] }>
                      <PriceInput onChange={ () => {} } placeholders={ placeholders } style={ { width: '60%', marginRight: 8 } } />
                    </Form.Item>
                    {index === fields.length - 1 ? (
                      <PlusCircleOutlined
                        onClick={ () => {add();} }
                        style={ { marginLeft: 5, position: 'relative', top: 5, color: '#3879d9', cursor: 'point', fontSize: 20 } } />
                    ) : null}
                    {fields.length > 1 ? (
                      <MinusCircleOutlined
                        onClick={ () => {
                          remove(field.name);
                        } }
                        style={ { marginLeft: 5, color: 'red', position: 'relative', top: 5, cursor: 'point', fontSize: 20 } } />
                    ) : null}
                  </Form.Item>
                ))}
              </div>
            );
          }}
        </Form.List>
      );
    };
    
    
    DynamicFieldSet.propTypes = {
      label: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired,
      placeholders: PropTypes.array.isRequired,
    };
    
    export default DynamicFieldSet;
    

    三、PriceInput组件

    /* eslint-disable react/prop-types */
    import React from 'react';
    import { Input } from 'antd';
    
    const InputGroup = Input.Group;
    
    
    const PriceInput = ({ size, value = {}, placeholders, onChange, index }) => {
      const handleFirstChange = e => {
        triggerChange({ key: e.target.value });
      };
    
      const handleSecondChange = e => {
        triggerChange({ value: e.target.value });
      };
    
      const triggerChange = changedValue => {
        if (onChange) {
          onChange({
            ...value,
            ...changedValue,
          }, index);
        }
      };
    
      return (
        <div style={ { width: '85%', display: 'inline-block' } }>
          <InputGroup compact>
            <Input
              onChange={ handleFirstChange }
              placeholder={ placeholders[0] || '' }
              size={ size }
              style={ { width: '50%' } }
              type='text'
              value={ value.key } />
            <Input
              onChange={ handleSecondChange }
              placeholder={ placeholders[1] || '' }
              size={ size }
              style={ { width: '50%' } }
              type='text'
              value={ value.value } />
          </InputGroup>
        </div>
      );
    };
    
    export default PriceInput;
    
    

    OVER~ 校验规则及个性化封装请根据自己实际项目操作!

    如果你有更好的办法,烦请留言我了

    相关文章

      网友评论

          本文标题:antdv4动态表单

          本文链接:https://www.haomeiwen.com/subject/aaibehtx.html