有一个需求是基于taro+react hooks 做h5页面,嵌套进微信小程序里
涉及到表单校验,查看了taro-ui的Form组件,发现并没有实现表单校验
so~安装async-validator 来实现表单校验(是一个表单的异步验证的第三方库,github.com/yiminghe/as…)
贴上代码
export const onValidateField = (value: ValidateSource, rules: Rules) => {
const validator = new Schema(rules);
return new Promise<any>((resolve) => {
// @ts-ignore
validator.validate(value, (errors, fields) => {
if (errors) {
resolve(errors);
} else {
const errMsg = Object.keys(rules).map((key) => {
return {
field: key,
message: undefined,
};
});
resolve(errMsg);
}
});
});
};
以下 FormItem 是自己封装的一个容纳错误信息的组件
const [FormValue, setFormValue] = useState<any>({
ContactName: "",
ContactPhone: "",
CorpName: "",
});
const [MsgList, setMsgList] = useState<any>(null);
const FormRules = {
ContactName: [
{ required: true, message: "请输入联系人" },
{
max: 50,
message: "联系人最多50位",
},
],
ContactPhone: [
{ required: true, message: "请输入手机号" },
{
validator: (rule, value) => {
return /^1[3-9]\d{9}$/.test(value);
},
message: "请输入正确的手机号",
},
],
}
// 格式表单错误信息为{ value:message }
export const getErrorMsgList = (errors: any[]) => {
let msgList = {};
errors?.map((error: { field: React.ReactText; message: any }) => {
msgList[error.field] = error?.message || "";
});
return msgList;
};
const setErrorMsgList = (errors) => {
const msgList = getErrorMsgList(errors);
setMsgList({ ...MsgList, ...msgList });
};
// 表单值change的时候校验
const onFormItemChange = async (label, value) => {
setFormValue({ ...FormValue, [label]: value });
const errors = await onValidateField(
{ [label]: value },
{ [label]: FormRules[label] },
);
setErrorMsgList(errors);
};
// 提交的时候校验
const onSubmit = async () => {
const errors = await onValidateField(FormValue, FormRules);
setErrorMsgList(errors);
let valid = !errors || errors.filter((error) => error.message).length <= 0;
if (valid) {
console.log("验证通过啦~");
}
};
<FormItem label="联系人" errorMsg={MsgList?.ContactName}>
<AtInput
border={false}
name="ContactName"
value={FormValue?.ContactName}
onChange={(value) => onFormItemChange("ContactName", value)}
placeholder="请输入联系人"
/>
</FormItem>
<FormItem label="手机号" errorMsg={MsgList?.ContactPhone}>
<AtInput
border={false}
type="phone"
name="ContactPhone"
value={FormValue?.ContactPhone}
onChange={(value) => onFormItemChange("ContactPhone", value)}
placeholder="请输入手机号码"
/>
</FormItem>