效果图:
选中第一项下拉框,第二第三项展示
点击添加条件,第二条仍然只展示第一项select框
后端返回数据格式:
ruleList:[{name:'通话时长',key:'TALK_TIME',type:’INT‘,unitName:'秒',operaObj:[{name:'>=',value:'>='},{name:'<=',value:'<='}],restrValues:null},{name:'是否成功',key:'IS_SUCCESS',type:’BOOLEAN‘,unitName:'',operaObj:[{name:'=',value:'='}],restrValues:[{name:'是',value:true},{name:'否',value:false}]},{name:'通话状态',key:'CALL_STATUS',type:’MULTI_SELECT‘,unitName:'',operaObj:[{name:'=',value:'in'}],restrValues:[{name:'黑名单',value:’1‘},{name:'忙碌',value:’2‘}]}
]
根据选中的第一项,动态展示第二项第三项,以及第三项的类型是下拉框还是input,和单位unitName
代码:
import { ModalForm } from '@ant-design/pro-form';
import type { FormInstance } from 'antd';const manageFormRef = useRef<FormInstance>();
const [formData, setFormDate] = useState({ruleConditionDTOList: [null]
});<ModalFormtitle='添加'// 弹窗开关,跟目前主要所写逻辑无关,可以先不管,按照你自己的弹窗开关事件即可open={visible}width={650}formRef={manageFormRef}layout='vertical'autoComplete='off'labelCol={{ span: 12 }}onFieldsChange={() => setFormDate(manageFormRef.current?.getFieldValue())}// 默认初始化值initialValues={{isAddToBlacklist: false,ruleConditionDTOList: [{}]}}// 弹窗关闭onOpenChange={onClose}// 提交表单onFinish={handleOnFinish}
>
<Form.Item label='同时满足以下条件'><Form.List name="ruleConditionDTOList">{(fields, { add, remove }) => (<>{fields.map((field, index) => (<Space key={field.key} style={{ display: 'flex', flexWrap: 'wrap', marginBottom: 8 }} align="baseline"><Form.Itemname={[field.name, 'key']}rules={[{ required: true, message: '请选择条件' }]}><Selectplaceholder="请选择条件"style={{ width: 200 }}onChange={(val) => handleChange(val, field, index)}>{ruleList && ruleList.map((item: any) => (<Select.Option value={item.key} fieldNames={item}>{item.name}</Select.Option>))}</Select></Form.Item>// 第一项有值,显示第二项{formData?.ruleConditionDTOList[index]?.key && <Form.Itemname={[field.name, 'operator']}rules={[{ required: true, message: '请选择' }]}><Select style={{ width: 100 }} placeholder="请选择">{ruleList && ruleList.find(v => formData.ruleConditionDTOList[index].key == v.key)?.operaObj.map((item: any) => (<Select.Option value={item.value}>{item.name}</Select.Option>))}</Select></Form.Item>}// 第一项有值,展示第三项,根据第一项的type,动态展示第三项是input或是select或是多选,我这里写了个函数{formData?.ruleConditionDTOList[index]?.key && getModel(formData?.ruleConditionDTOList[index]?.key, field, index)}// form表单组的长度大于1,显示删除按钮,否则隐藏{fields.length > 1 &&<DeleteOutlinedstyle={{ color: 'rgb(43, 132, 255)' }}className="dynamic-delete-button"onClick={() => remove(field.name)}/>}</Space>))}<Form.Item><Button style={{ width: '100px' }} type="primary" onClick={() => add()} block>添加条件</Button></Form.Item></>)}</Form.List>
</Form.Item>
</ModalForm>// 根据type类型动态展示第三项要展示的内容
const getModel = (key: any, field: any, index: Number) => {const item = ruleList.find((v: any) => v.key == key);const types = {INT: (field: any, item: any) => {return <Form.Itemname={[field.name, 'value']}rules={[{ required: true, message: '请输入' }]}><Input placeholder="请输入" style={{ width: 100 }} suffix={item.unitName} /></Form.Item>},// 多选下拉MULTI_SELECT: (field: any, item: any) => {return <Form.Itemname={[field.name, 'value']}rules={[{ required: true, message: '请选择' }]}><Select mode="multiple" style={{ width: 200 }}>{item.restrValues.map((v: any) => (<Select.Option value={v.value}>{v.name}</Select.Option>))}</Select></Form.Item>},BOOLEAN: (field: any, item: any) => {return <Form.Itemname={[field.name, 'value']}rules={[{ required: true, message: '请选择' }]}><Select style={{ width: 100 }}>{item.restrValues.map((v: any) => (<Select.Option value={v.value}>{v.name}</Select.Option>))}</Select></Form.Item>}}return types[item.type](field, item, index) ?? null;},// 选中第一项第二三项清空const handleChange = (val: any, field: any, index: any) => {const { ruleConditionDTOList } = formDataruleConditionDTOList[index] = Object.assign(ruleConditionDTOList[index] ?? {}, {key: val,operator: null,value: undefined})manageFormRef.current?.setFieldValue('ruleConditionDTOList', ruleConditionDTOList);setFormDate(manageFormRef.current?.getFieldValue());console.log(manageFormRef.current?.getFieldValue(), '置空');}
// 编辑时数据回显,后端返回的数据
data:{ruleConditionDTOList:[{name:'通话状态',key:'CALL_STATUS',type:'MULTI_SELECT',operator:'in',unitName:'',value:'1,2'},{name:'通话时长',key:'TALK_TIME',type:'INT',operator:'>=',unitName:'秒'}]
}
回显
useEffect(()=>{// 点击编辑,传的tagData单行rowif(tagData){// 由于我获取接口都是异步,赋值时需要setTimeout一下setTimeout(() => {const { ruleConditionDTOList: list } = tagDatalet arr:any = []list?.map((v:any) => {// 写个辅助函数,根据不同type,对value进行不同的操作const getValue = (type: any) => {const types = {INT: () => {return v.value},BOOLEAN: () => {return Boolean(v.value)},MULTI_SELECT: () => {const value = v?.value.split(',')return value}}return types[type]() ?? ''}const object = {name: v.name,key: v.key,operator: v.operator,value: getValue(v.type),type: v.type,unitName: v.unitName}arr.push(object)})manageFormRef.current?.setFieldsValue({ruleConditionDTOList: arr})setFormDate(manageFormRef.current?.getFieldsValue())}, 300);}
},[tagData])
提交数据部分就不写了,提交跟接口相对应的数据就行