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

Vue3+Vite环境下vee-validate的handleSubmit函数失效问题

Vee-Validate handleSubmit无输出,提交回调不执行

问题描述

使用Vee-Validate结合Yup验证注册表单,点击提交按钮后,handleSubmit包裹的回调函数没有任何日志输出,预期的表单值打印完全没触发。

代码复现

<script setup lang="ts">
import type { User } from '@/models/user';
import { useUserStore } from '@/stores/client/user';
import { ref } from 'vue';
import { useForm } from 'vee-validate';
import * as yup from 'yup';

const schema = yup.object({
    name: yup.string().required('Name is required'),
    surnames: yup.string().required('Surname is required'),
    birthdate: yup.date().nullable().required('Birthdate is required').transform((value, originalValue) => originalValue === '' ? null : value),
    email: yup.string().email('Email is not valid').required('Email is required'),
    password: yup.string().min(8, 'Password is too short - should be 8 chars minimum.').required('Password is required'),
    passwordConfirmation: yup.string()
        .oneOf([yup.ref('password'), undefined], 'Passwords must match')
        .required('Password confirmation is required'),
});

const { handleSubmit, defineField, meta, errors } = useForm({
    validationSchema: schema
});


const [name, nameAttrs] = defineField('name');
const [surnames, surnamesAttrs] = defineField('surnames');
const [email, emailAttrs] = defineField('email');
const [password, passwordAttrs] = defineField('password');
const [passwordConfirmation, passwordConfirmationAttrs] = defineField('passwordConfirmation');

const onSubmit = handleSubmit(values => {
    console.log('Handling submit:', values);
    console.log("Form submitted");
    console.log("Values:", values);
    console.log("Is form valid?", meta.value.valid);
});
</script>


<template>
    <section class="form-section">
        <div class="form-container">
            <h1 class="form-title">Create an account</h1>
            <form @submit.prevent="onSubmit" novalidate>
                <input type="text" v-model="name" v-bind="nameAttrs" placeholder="Your name" class="input-field" required>
                <span v-if="errors.name" class="error-message">{{ errors.name }}</span>

                <input type="text" v-model="surnames" v-bind="surnamesAttrs" placeholder="Your surnames" class="input-field" required>
                <span v-if="errors.surnames" class="error-message">{{ errors.surnames }}</span>

                <input type="email" v-model="email" v-bind="emailAttrs" placeholder="Your email" class="input-field" required>
                <span v-if="errors.email" class="error-message">{{ errors.email }}</span>

                <input type="password" v-model="password" v-bind="passwordAttrs" placeholder="Password" class="input-field" required>
                <span v-if="errors.password" class="error-message">{{ errors.password }}</span>

                <input type="password" v-model="passwordConfirmation" v-bind="passwordConfirmationAttrs" placeholder="Confirm password" class="input-field" required>
                <span v-if="errors.passwordConfirmation" class="error-message">{{ errors.passwordConfirmation }}</span>

                <button type="submit" class="submit-button">Create an account</button>
                <p class="link-text">Already have an account? <a href="/login" style="color: #007BFF;">Login here</a></p>
            </form>
        </div>
    </section>
</template>

问题根源

你的Yup验证规则中定义了birthdate字段并标记为必填,但在模板里完全没有对应这个字段的输入控件。Vee-Validate的handleSubmit默认仅在表单所有字段验证通过时才会执行传入的回调函数,由于birthdate字段始终缺失值,表单一直处于验证失败状态,导致回调无法触发。

解决方案

方案1:添加缺失的birthdate输入框(如果该字段确实需要)

在<script setup>中添加字段绑定:

const [birthdate, birthdateAttrs] = defineField('birthdate');

在模板的表单中添加对应的输入控件和错误提示:

<input type="date" v-model="birthdate" v-bind="birthdateAttrs" placeholder="Your birthdate" class="input-field">
<span v-if="errors.birthdate" class="error-message">{{ errors.birthdate }}</span>

方案2:移除birthdate字段的验证规则(如果该字段非必填)

修改Yup schema,删除birthdate字段或者去掉required约束:

const schema = yup.object({
    name: yup.string().required('Name is required'),
    surnames: yup.string().required('Surname is required'),
    // 移除birthdate字段,或者改为非必填
    // birthdate: yup.date().nullable(),
    email: yup.string().email('Email is not valid').required('Email is required'),
    password: yup.string().min(8, 'Password is too short - should be 8 chars minimum.').required('Password is required'),
    passwordConfirmation: yup.string()
        .oneOf([yup.ref('password'), undefined], 'Passwords must match')
        .required('Password confirmation is required'),
});

验证方法

可以在模板中添加表单状态提示,快速确认表单是否有效:

<p>表单是否有效:{{ meta.value.valid }}</p>

点击提交时如果显示false,说明存在未通过验证的字段,可结合errors对象排查具体问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:47:08