formily 实用用法
自定义组件校验
校验失败后给自定义组件设置失败状态 组件内部通过定义的 props status, errorMsg 字段来控制状态显示
// 校验失败后触发
createForm({
effects: () => {
// 监听某个字段校验触发失败
onFieldValidateFailed('storePic', (field) => {
// 校验失败时给自定义组件设置状态,用于展示失败状态
// 这里没有设置errorMsg,利用 formily 自带的进行展示
field.componentProps.status = 'error'
})
}
})
// 字段校验器, 字段为null,[] 校验
'x-validator': [
{ required: true, message: '请上传图片' },
{
validator: (val: any) => {
if (val?.fileList.length === 0) return '请上传图片'
},
triggerType: 'onBlur'
}
],
// 组件内部
const comp = (props) => {
const { status } = props
return status === 'error' ? 'error' : 'success'
}
// 上述方式还需要在组件值变化时清空error状态
onFieldChange('storePic', ['value'], (field: any) => {
if (field.componentProps.status) {
field.componentProps.status = ''
}
})
能否利用一个高阶函数简化上述操作呢
const factoryCustomField = (Comp: any): any => {
const CustomComp = (props: any) => {
const [status, setStatus] = useState("");
const field: any = useField();
useFormEffects(() => {
// 监听某个字段校验触发失败
onFieldValidateFailed(field.props.name, (field) => {
// 校验失败时给自定义组件设置状态,用于展示失败状态
setStatus("error");
});
});
// 清除 error
const handleChange = (val: any) => {
if (status === "error") setStatus("");
console.log("----lai", field);
field.setSelfErrors([
{
validator: (val: any) => {
if (val?.fileList.length === 0) return "请上传图片";
},
triggerType: "onBlur",
},
]);
props.onChange(val);
};
return <Comp {...props} status={status} onChange={handleChange} />;
};
return CustomComp;
};
设置 form 表单的状态,遇到的问题
import { createForm, onFieldChange } from "@formily/core";
createForm({
effects: () => {
onFieldChange("type", ["value"], (field: any, form: any) => {
form.setFieldState("workTime", (state: any) => {
state.componentProps.required = field.value === "offline";
});
form.setFieldState("address", (state: any) => {
state.required = field.value === "offline";
});
// 根据某个字段控制组件的显示隐藏,若存在必填字段,则需要先设置必填之后再进行隐藏操作
// 等待form表单变更后,再进行状态修改操作
setTimeout(() => setIsShowBusiness(field.value === "offline"));
});
},
});
设置字段 disabled
form.setFieldState("merchant", (state: any) => {
state.disabled = true;
});
校验某些字段
// 自定义字段
validatorActions.validator({
exclude: [
"PriceDetail", // 组件名
"OrderUserMobile",
"ContactUserInputPhone",
"ContactUserInputName",
],
});
// formily 字段,值为字段 name
const validate = await Promise.all([
form.validate("org"),
form.validate("buyCount"),
form.validate("dividerMoney"),
]);
组件内部 form 某个字段 change 监听
useFormEffects(() => {
onFieldValueChange("number", todoFun);
onFieldValueChange("cars", clearMoney);
});