效果图:
选中第一项下拉框,第二第三项展示
点击添加条件,第二条仍然只展示第一项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]
});
<ModalForm
title='添加'
// 弹窗开关,跟目前主要所写逻辑无关,可以先不管,按照你自己的弹窗开关事件即可
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.Item
name={[field.name, 'key']}
rules={[{ required: true, message: '请选择条件' }]}
>
<Select
placeholder="请选择条件"
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.Item
name={[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 &&
<DeleteOutlined
style={{ 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.Item
name={[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.Item
name={[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.Item
name={[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 } = formData
ruleConditionDTOList[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单行row
if(tagData){
// 由于我获取接口都是异步,赋值时需要setTimeout一下
setTimeout(() => {
const { ruleConditionDTOList: list } = tagData
let 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])
提交数据部分就不写了,提交跟接口相对应的数据就行