如何使用Yup在同一输入框中验证邮箱或手机号?
解决Yup验证邮箱/手机号二选一格式的问题
你当前的代码通过链式调用.matches(phoneValidation).matches(emailValidation),会要求输入内容同时符合手机号和邮箱两种格式,这显然无法实现二选一的校验需求,需要调整校验逻辑让输入满足其中一种格式即可。
方案一:使用Yup的test自定义校验(推荐)
这种方式逻辑清晰,便于自定义错误提示,灵活度更高:
type forgotPasswordData = { email_or_phone: string; } const phoneValidation = /^([\s\(\)\-]*\d[\s\(\)\-]*){8}$/; const emailValidation = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const forgotPasswordSchema = yup.object().shape({ email_or_phone: yup.string() .required('请输入邮箱或手机号') .test( 'is-valid-email-or-phone', '请输入有效的邮箱或手机号', (value) => phoneValidation.test(value) || emailValidation.test(value) ) }); // 其余组件代码保持不变
方案二:合并正则表达式
将手机号和邮箱的正则用|合并为一个,直接通过matches校验:
注意:合并时使用非捕获分组确保正则边界匹配正确,避免出现异常匹配
type forgotPasswordData = { email_or_phone: string; } const phoneValidation = /^([\s\(\)\-]*\d[\s\(\)\-]*){8}$/; const emailValidation = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // 合并两个正则 const combinedValidation = new RegExp(`^(?:${phoneValidation.source}|${emailValidation.source})$`); const forgotPasswordSchema = yup.object().shape({ email_or_phone: yup.string() .required('请输入邮箱或手机号') .matches(combinedValidation, '请输入有效的邮箱或手机号') }); // 其余组件代码保持不变
补充:显示错误提示
记得在输入框下方添加错误信息展示,提升用户体验:
<Input type='text' placeholder='Email or mobile number' error={errors.email_or_phone} {...register("email_or_phone")} /> {errors.email_or_phone && <span style={{ color: 'red', fontSize: '0.875rem' }}> {errors.email_or_phone.message} </span>}
内容的提问来源于stack exchange,提问作者alanfljesus
相关产品推荐
相关产品推荐

