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

Vuelidate如何使用OR规则实现邮箱或手机号二选一必填校验

问题说明
  • 目标校验逻辑:表单中手机号、邮箱两个字段,任意一项填写完成且格式正确,即可通过校验
  • 现存卡点:未掌握Vuelidate中or校验规则的正确使用方式,查阅官方文档、公开技术资料未找到同场景的可参考实现,运行代码时触发校验相关报错
  • 相关参考材料:已提供对应代码实现截图、运行报错截图
正确实现方案

核心注意点

or作为跨字段逻辑校验器,不能直接嵌套在单个字段的校验规则内部——单字段规则下只能获取当前字段的值,无法读取同表单其他字段的内容,这也是触发校验报错的核心原因。or规则需要定义在与待校验字段同级的规则层级,才能拿到完整表单数据做逻辑判断。

Vuelidate 2.x(适配Vue3)写法

  1. 先引入依赖的校验方法
import { useVuelidate } from '@vuelidate/core'
import { or } from '@vuelidate/validators'
  1. 定义校验规则
// 表单响应式数据
const form = ref({
  phone: '',
  email: ''
})

// 校验规则
const rules = {
  phone: {
    // 单字段只做格式校验:字段为空时跳过格式校验,不触发报错
    formatCheck: (val) => {
      if (!val) return true
      // 替换为实际业务使用的手机号正则,示例为国内11位手机号规则
      return /^1[3-9]\d{9}$/.test(val)
    }
  },
  email: {
    // 邮箱同理:仅当字段有值时校验格式
    formatCheck: (val) => {
      if (!val) return true
      return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val)
    }
  },
  // 跨字段or规则:和phone、email字段同级定义
  contactFilled: {
    $validator: or(
      // 分支1:手机号有值且格式正确
      (_, formInstance) => !!formInstance.phone && /^1[3-9]\d{9}$/.test(formInstance.phone),
      // 分支2:邮箱有值且格式正确
      (_, formInstance) => !!formInstance.email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formInstance.email)
    ),
    $message: '请填写手机号或邮箱其中一项'
  }
}

// 初始化校验实例
const v$ = useVuelidate(rules, form)
  1. 表单提交时校验
const submitForm = async () => {
  const isFormValid = await v$.value.$validate()
  if (!isFormValid) return
  // 校验通过,执行后续提交逻辑
}

Vuelidate 1.x(适配Vue2)写法

import { validationMixin } from 'vuelidate'
import { or } from 'vuelidate/lib/validators'

export default {
  mixins: [validationMixin],
  data() {
    return {
      form: {
        phone: '',
        email: ''
      }
    }
  },
  validations() {
    const phoneReg = /^1[3-9]\d{9}$/
    const emailReg = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    return {
      form: {
        phone: {
          formatCheck: (val) => !val || phoneReg.test(val)
        },
        email: {
          formatCheck: (val) => !val || emailReg.test(val)
        },
        contactFilled: or(
          (formVal) => !!formVal.phone && phoneReg.test(formVal.phone),
          (formVal) => !!formVal.email && emailReg.test(formVal.email)
        )
      }
    }
  },
  methods: {
    submitForm() {
      this.$v.$touch()
      if (this.$v.$error) return
      // 校验通过执行提交
    }
  }
}

常见踩坑

  • 不要给phone、email字段单独加required规则,否则字段为空时会先触发必填报错,阻断or规则的逻辑判断
  • 自定义格式校验一定要做空值跳过处理,避免用户未填写的字段触发格式报错
  • 不要把or规则写在单个字段的规则对象内部,否则无法获取另一个字段的取值

内容的提问来源于stack exchange,提问作者Vascob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:33:21