要實現一個功能動態表單中巢狀動態表單如下:
仔細看看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