Yup表单验证核心原理与项目中的踩坑经验分享
先看效果,再看代码
最近在做一个表单校验的需求,本来想自己写一堆if-else来判断,但后来发现Yup这个库简直是神器。直接上个简单例子:
import * as Yup from 'yup';
const schema = Yup.object().shape({
name: Yup.string().required("名字不能为空").min(2, "名字太短了"),
age: Yup.number().required("年龄必填").positive("年龄不能是负数").integer("年龄必须是整数")
});
schema.validate({ name: "张", age: -5 })
.catch(err => console.log(err.errors));
// 输出:["名字太短了", "年龄不能是负数"]
上面这段代码亲测有效,几行就搞定了复杂的校验逻辑。
这个场景最好用
我最常用Yup的场景就是配合React Hook Form做表单校验。两者结合使用简直不要太爽:
import { useForm } from "react-hook-form";
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';
const schema = Yup.object().shape({
email: Yup.string().email("邮箱格式不对").required("邮箱必填"),
password: Yup.string().min(6, "密码至少6位").required("密码必填")
});
function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(schema)
});
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <p>{errors.email.message}</p>}
<input type="password" {...register("password")} />
{errors.password && <p>{errors.password.message}</p>}
<button type="submit">提交</button>
</form>
);
}
这种方式我用了好几个项目,建议直接用这种方式,省心省力。
踩坑提醒:这三点一定注意
虽然Yup很好用,但我在这几个地方踩过坑,给大家提个醒:
- 异步校验顺序问题:如果你用了test方法做自定义校验,记得要return一个Promise,不然校验结果可能会乱序。
- 类型转换陷阱:Yup会在校验前自动转换数据类型,比如字符串”123″会被转成数字123,这点要注意。
- 嵌套对象校验:处理深层嵌套对象时,.shape()里面还要继续写.shape(),别忘了每个层级都要定义。
一些高级用法和技巧
除了基本校验,Yup还有一些很实用的高级功能:
// 动态校验规则
const dynamicSchema = Yup.object().shape({
password: Yup.string().required(),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password'), null], "两次密码不一致")
});
// 自定义校验
const customSchema = Yup.object().shape({
username: Yup.string()
.test(
"unique-username",
"用户名已存在",
async (value) => {
const response = await fetch(https://jztheme.com/api/checkUsername?name=${value});
const data = await response.json();
return !data.exists;
}
)
});
这里特别要说下自定义校验,刚开始我总是忘记加async/await,折腾了半天才发现问题出在这。
说点别的
其实Yup还能和很多其他库搭配使用,比如Formik、Redux Form之类的。不过我个人更喜欢React Hook Form,轻量又灵活。对了,Yup现在也支持TypeScript了,类型提示很友好。
以上是我个人对Yup的完整讲解,有更优的实现方式欢迎评论区交流。这个技术的拓展用法还有很多,后续会继续分享这类博客。
本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。

暂无评论