如何用Yup实现密码不包含用户名的跨属性校验?
解决Yup密码校验不能包含用户名的问题
你之前用matches的写法没法实现动态校验,因为正则是静态定义的,没办法实时获取表单里的用户名值。正确的做法是使用Yup的test方法,它能访问整个表单的上下文数据,从而拿到当前输入的用户名来做校验。
修改后的完整代码如下:
export const schema = Yup.object({ username: Yup.string() .required("Username is required") .matches( /^[a-zA-Z0-9_-]+$/, "The username should contain only alphanumeric characters, underscores and hyphens" ), password: Yup.string() .required("Password is required") .matches( /^(?=.*?[A-Z])(?=.*[a-z])(?=.*\d)(?=.*\W).{8,}$/, "The password should contain upper and lowercase letters, numbers and special characters" ) .test( "not-contain-username", "The password should not contain the username", function(value) { // 从表单上下文获取用户名 const username = this.parent.username; // 空值直接通过(前面已有必填校验) if (!value || !username) return true; // 不区分大小写校验,若要区分大小写,改成!value.includes(username)即可 return !value.toLowerCase().includes(username.toLowerCase()); } ) });
关键说明:
test方法支持自定义校验逻辑,通过this.parent可以获取到整个表单的所有字段值,从而拿到实时的用户名。- 校验函数里先判断密码和用户名是否为空,避免空值导致的逻辑错误,因为前面已经配置了
required校验,空值场景会被提前拦截。 - 如果想用正则实现相同逻辑,也可以动态生成正则表达式:
.test( "not-contain-username", "The password should not contain the username", function(value) { const username = this.parent.username; if (!value || !username) return true; // 动态生成不区分大小写的正则 const usernameRegex = new RegExp(username, 'i'); return !usernameRegex.test(value); } )
内容的提问来源于stack exchange,提问作者Robert Gabriel
相关产品推荐
相关产品推荐

