You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:35:19