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

Vee-validate结合Yup动态输入字段不验证且无错误提示问题

问题:VeeValidate + Yup 动态生成嵌套字段验证失效

这是此前相关问题的跟进提问,因需循环渲染字段,尝试动态配置VeeValidate与Yup,但复刻静态配置方式后,动态字段既不触发验证也不显示错误。

脚本代码

import { useForm } from 'vee-validate'
import * as yup from 'yup'

const {
  values,
  errors,
  defineComponentBinds,
  isSubmitting,
  setFieldValue,
  handleSubmit
} = useForm({
  validationSchema: yup.object({
    moduleValidationInputs: yup.object(moduleValidationSchemes.value)
  })
})

const moduleValidationSchemes = ref({})
const moduleValidationInputs = ref({})

onMounted(() => {
  newModuleFields.value.map(nmf => {
    if (nmf.rules && nmf.rules.required) {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).required()
    } else moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).nullable()

    moduleValidationInputs.value[nmf.uniqueName] = defineComponentBinds(`moduleValidationInputs.${nmf.uniqueName}`)
  })
})

模板代码

<div v-for="(requiredField, rfx) in requiredFields" :key="rfx" class="col-6">
  <p>{{ errors }}</p>
  <span class="p-float-label">
    <InputText
     v-bind="moduleValidationInputs[requiredField.uniqueName]"
     class="w-full border-left-3 border-red-600"
    />
    <label>{{ requiredField.label }}</label>
  </span>
</div>

验证对比

将验证Schema替换为静态配置时,验证正常生效:

moduleValidationInputs: yup.object({
  lead_company: yup.string().label('Company').required()
})

疑问:是否VeeValidate的useForm不支持动态生成Yup对象作为validationSchema?我的操作哪里有误?


解决方案

问题核心是**useForm初始化时,moduleValidationSchemes.value还是空对象**,后续修改ref值不会触发VeeValidate自动更新验证规则——因为validationSchema在useForm初始化时就已固化,不会响应ref的变化。

下面提供两种可行的解决方式:

方式一:延迟初始化useForm

等字段配置就绪后再调用useForm,确保初始化时验证规则已完整:

import { useForm } from 'vee-validate'
import * as yup from 'yup'

const moduleValidationSchemes = ref({})
const moduleValidationInputs = ref({})
let formContext = null

onMounted(() => {
  // 先构建完整的验证规则
  newModuleFields.value.forEach(nmf => {
    if (nmf.rules?.required) {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).required()
    } else {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).nullable()
    }
  })

  // 再初始化表单
  formContext = useForm({
    validationSchema: yup.object({
      moduleValidationInputs: yup.object(moduleValidationSchemes.value)
    })
  })

  // 绑定字段
  newModuleFields.value.forEach(nmf => {
    moduleValidationInputs.value[nmf.uniqueName] = formContext.defineComponentBinds(`moduleValidationInputs.${nmf.uniqueName}`)
  })
})

// 按需解构表单方法供外部使用
const { values, errors, isSubmitting, handleSubmit } = computed(() => formContext || {})

方式二:用setValidationSchema动态更新规则

利用useForm返回的setValidationSchema方法,在构建完规则后动态替换验证Schema:

import { useForm } from 'vee-validate'
import * as yup from 'yup'

const {
  values,
  errors,
  defineComponentBinds,
  isSubmitting,
  setFieldValue,
  handleSubmit,
  setValidationSchema // 新增该方法
} = useForm({
  // 先初始化空的基础Schema
  validationSchema: yup.object({
    moduleValidationInputs: yup.object({})
  })
})

const moduleValidationSchemes = ref({})
const moduleValidationInputs = ref({})

onMounted(() => {
  // 构建验证规则
  newModuleFields.value.forEach(nmf => {
    if (nmf.rules?.required) {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).required()
    } else {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).nullable()
    }

    moduleValidationInputs.value[nmf.uniqueName] = defineComponentBinds(`moduleValidationInputs.${nmf.uniqueName}`)
  })

  // 动态更新验证规则
  setValidationSchema(yup.object({
    moduleValidationInputs: yup.object(moduleValidationSchemes.value)
  }))
})

额外提示

  • 遍历数组执行副作用操作时,用forEach比map更语义化(map本意是返回新数组,而非执行副作用)。
  • 如果newModuleFields是异步获取的,要等数据返回后再执行规则构建和字段绑定逻辑,比如放在watch里监听newModuleFields的变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:04:57