完整的篇幅请看这篇文章:https://editor.csdn.net/md/?articleId=135146594
如果想要将自定义的组件和antd表单实现绑定校验表单,需要使用antd官网自带的组件方可实现边框自动变红,这时候就要求使用 select 或者 input 组件或者其他组件进行改造。
记住,如果是自定义的div组件,里边没有表单组件(例如Input、Select之类的,还有antd自带的其他表单项),是不会触发边框变红的校验的,最多只会出现为空提示文案(通过onChange的接管实现的提示)!!!
方案一:Antd组件扩展为自定义组件
const MapSelector = ({ title, onChange, value, disabled, btnDisable, ...otherProps }) => {
const [visible, setVisible] = useState(false);
const [addressList, setAddressList] = useState([]);
const [resultList, setResultList] = useState([]);
const [areaCode, setAreaCode] = useState();
const [options, setOptions] = useState([]);
const [values, setValues] = useState([]);
useEffect(() => {
if (Array.isArray(value) && value.length) {
setAddressList(value);
setResultList(value);
}
}, [value]);
useEffect(() => {
const _options = [];
const _values = [];
resultList?.forEach((item) => {
_options.push({
label: item.address,
value: item.address,
});
_values.push(item.address);
});
setOptions(_options);
setValues(_values);
}, [resultList]);
const handleCancel = () => {
setVisible(false);
};
const onSelectChange = (val, currentRecord, mapResource) => {
const temp = [];
if (!addressList.length || addressList.findIndex((item) => item.address === val) === -1) {
temp.push({ address: val, longitude: currentRecord.lng, latitude: currentRecord.lat, mapResource });
}
const result = [...addressList, ...temp];
setAddressList(result);
setResultList(result);
onChange(result);
};
return
(<>
<div className={styles.mapWrapper}>
<Select
style={{ width: '100%', minWidth: 400 }}
placeholder={otherProps.placeholder}
showArrow={false}
popupClassName={styles.hiddenDropdown}
value={values}
mode="tags"
options={options}
/>
<div className={styles.rightBtn}>
{resultList.length ? (
<Icon
size={16}
icon="icon-system_tips_flat_circle-close"
color="#BCC1CD"
onClick={() => {
setAddressList([]);
setResultList([]);
onChange([]);
}}
style={{ marginRight: '8px' }}
/>
) : null}
<span className={styles.selected} onClick={openMapModal}>
<Icon icon="icon-system_tips_line_3_plus" size={12} style={{ marginRight: '4px' }} />
请选择
</span>
</div>
</div>
<MapModal
visible={visible}
handleCancel={handleCancel}
onChange={onSelectChange}
title={title}
areaCode={areaCode}
onAreaChange={(val) => {
setAreaCode(val);
}}
{...otherProps}
/>
</>)
}
方案二:自主控制(经过验证,不可靠,不建议)
const [isFormValidate, setIsFormValidate] = useState(false);
const { formValueMap, form } = useContext(RenderContext);
useEffect(() => {
// isFormValidate用作自定义地图选择表单校验边框变红
let _isFormValidate = false;
if (areaFormat === 2) {
const formErrors = form.getFieldError(fId);
const currProp = form.getFieldsValue(formId);
if (formErrors.length && formErrors[0] === '请选择') {
_isFormValidate = true;
}
}
setIsFormValidate(_isFormValidate);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [areaFormat, form, formId, intl, form.getFieldError(fId), fId]);
const getFormId = useCallback(
(suffix = '_param_AreaDetail') => {
if (Array.isArray(formId)) {
return [formId[0], `${formId[1]}${suffix}`];
}
return `${formId}${suffix}`;
},
[formId],
);
const onMapSelectChange = (val) => {
// 先赋值
form.setFieldValue(getFormId(''), val);
// 接着启动主动校验,可以更新表单的状态
form.validateFields();
setIsFormValidate(false);
};
return (
<Form.Item name={getFormId('')}>
<MapSelector
onChange={onMapSelectChange}
title={intl.formatMessage({ id: 'LMID_00005759' })}
customSplitStr="/"
isFormValidate={isFormValidate} // 让子组件边框变红字段
{...optionsProps}
{...otherprops}
/>
</Form.Item>
)