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

vee-validate中validateOnMount: false不生效问题求助

问题描述

我有一个字段数组,希望仅在用户触碰字段后才触发校验。尝试设置validateOnMount: false,但该配置仍未生效,相关代码如下:

<template>
  <form @submit="onSubmit" novalidate>
    <div v-for="(field, idx) in fields" :key="field.key">
      <input v-model="field.value" type="url" />
      <span>{{ errors }}</span>
      <button type="button" @click="remove(idx)">Remove</button>
    </div>

    <button type="button" @click="push('')">Add</button>

    <button>Submit</button>
  </form>
</template>

<script setup>
import { useForm, useFieldArray } from 'vee-validate';
import * as yup from 'yup';

const { handleSubmit, errors } = useForm({
  validationSchema: yup.object({
    links: yup.array().of(yup.string().required()),
  }),
  initialValues: {
    links: [''],
  },
  validateOnMount: false,
});

const { remove, push, fields } = useFieldArray('links');

const onSubmit = handleSubmit((values) => {
  console.log(JSON.stringify(values, null, 2));
});
</script>

表单加载后立即显示必填错误

解决方案

问题根源在于:validateOnMount: false仅控制表单挂载时的整体校验,但yup的required()规则会对初始空值直接触发校验,且useFieldArray生成的字段默认会在输入时触发校验。可以通过以下方式修复:

  1. 调整Yup校验规则,仅在字段被触碰后启用必填校验
    利用vee-validate提供的$touched上下文变量,让必填规则仅在字段被用户触碰后生效:

    links: yup.array().of(
      yup.string().trim().when('$touched', {
        is: true,
        then: (schema) => schema.required('链接不能为空').url('请输入有效的URL'),
        otherwise: (schema) => schema.notRequired()
      })
    )
    
  2. 关闭输入时的自动校验
    在useForm配置中添加validateOnInput: false,避免用户输入过程中频繁触发校验:

    const { handleSubmit, errors } = useForm({
      // ...其他配置
      validateOnInput: false,
    });
    
  3. 精准绑定单个字段的错误信息
    原代码中直接渲染{{ errors }}会展示所有错误,改为针对每个数组项显示对应错误:

    <span>{{ errors.links?.[idx] }}</span>
    

修改后的完整代码:

<template>
  <form @submit="onSubmit" novalidate>
    <div v-for="(field, idx) in fields" :key="field.key">
      <input v-model="field.value" type="url" />
      <span>{{ errors.links?.[idx] }}</span>
      <button type="button" @click="remove(idx)">Remove</button>
    </div>

    <button type="button" @click="push('')">Add</button>

    <button>Submit</button>
  </form>
</template>

<script setup>
import { useForm, useFieldArray } from 'vee-validate';
import * as yup from 'yup';

const { handleSubmit, errors } = useForm({
  validationSchema: yup.object({
    links: yup.array().of(
      yup.string().trim().when('$touched', {
        is: true,
        then: (schema) => schema.required('链接不能为空').url('请输入有效的URL'),
        otherwise: (schema) => schema.notRequired()
      })
    ),
  }),
  initialValues: {
    links: [''],
  },
  validateOnMount: false,
  validateOnInput: false,
});

const { remove, push, fields } = useFieldArray('links');

const onSubmit = handleSubmit((values) => {
  console.log(JSON.stringify(values, null, 2));
});
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:42:47