【react】實現動態表單中巢狀動態表單

文學少女發表於2020-07-03

要實現一個功能動態表單中巢狀動態表單如下:

 仔細看看antd的文件其實不難 具體步驟如下(程式碼用ts寫的)

1.建立一個 名為 ConcatRegion的元件(動態表單A)程式碼如下

介面如下:

interface ConcatRegionProps {
    form: ReturnType<typeof useForm>[0];
}

interface ConcatRegionItemProps {
    index: number;
    form: ReturnType<typeof useForm>[0];
    field: any;
}

  

export function ConcatRegion({ form }: ConcatRegionProps) {
    return (
        <>
            <Form.Item label="策略">
                <Form.List name="totalStrategy">
                    {(fields, { add, remove }) => {
                        return (
                            <div className={styles.concat_regin_widget}>
                                {fields.map((field, index) => (
                                    <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                        <ConcatRegionItem index={index} form={form} field={field} />
                                        <DeleteTwoTone twoToneColor="#ff7875" onClick={() => remove(field.name)} />
                                    </Space>
                                ))}

                                <Form.Item>
                                    <Button
                                        type="dashed"
                                        className={styles.btn_blue_dashed}
                                        onClick={() => add()}
                                        block
                                    >
                                        <PlusOutlined className={styles.icon} /> 新增策略
                                    </Button>
                                </Form.Item>
                            </div>
                        );
                    }}
                </Form.List>
            </Form.Item>
        </>
    );
}

 2.建議一個名為ConcatRegionItem的表單(動態表單B) 程式碼如下:

export function ConcatRegionItem({ index, form, field }: ConcatRegionItemProps) {
    return (
        <>
            <Form.Item
                label={`策略${index + 1}`}
                name={[field.name, 'strategy']}
                fieldKey={[field.fieldKey, 'strategy']}
            >
                <Form.List name={[field.name, 'strategy']}>
                    {(fields, { add, remove }) => {
                        return (
                            <div>
                                {fields.map((innerField, index) => {
                                    return (
                                        <Space
                                            key={innerField.key}
                                            style={{ display: 'flex', marginBottom: 8 }}
                                            align="start"
                                        >
                                            <Form.Item
                                                {...innerField}
                                                name={[innerField.name, 'area']}
                                                fieldKey={[innerField.fieldKey, 'area']}
                                                rules={[{ required: true, message: '請選擇區域' }]}
                                            >
                                                <SelectMainArea />
                                            </Form.Item>

                                            <Form.Item
                                                {...innerField}
                                                name={[innerField.name, 'mainRegion']}
                                                fieldKey={[innerField.fieldKey, 'mainRegion']}
                                                rules={[{ required: true, message: '請選擇國家' }]}
                                            >
                                                <Select style={{ width: '150px' }} placeholder="國家">
                                                    <Option value="1">一區</Option>
                                                    <Option value="2">二區</Option>
                                                </Select>
                                            </Form.Item>
                                            {index === fields.length - 1 && <PlusCircleTwoTone onClick={() => add()} />}
                                            {index >= 1 && (
                                                <MinusCircleTwoTone onClick={() => remove(innerField.name)} />
                                            )}
                                           
                                        </Space>
                                    );
                                })}

                                {!fields.length && (
                                    <Form.Item>
                                        <Button type="dashed" onClick={() => add()} block>
                                            <PlusOutlined /> 新增資料配置
                                        </Button>
                                    </Form.Item>
                                )}
                            </div>
                        );
                    }}
                </Form.List>
            </Form.Item>
        </>
    );
}

 注意:這裡要把第一個外層表單的feild帶過來~,傳遞給子元件用於做子元件的 Form.Item的name

   元件  <SelectMainArea />為聯動select 帶值回來到 ConcatRegionItem

 

相關文章