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

Vue3结合Bootstrap与VeeValidate 4如何正确展示表单校验错误信息

修复后完整代码

<template>
<Form as="form" @submit.prevent="onFormSubmit" class="needs-validation" :class="{ 'was-validated': wasValidated }"> 
    <div class="form-group">
        <label for="firstNameId">First Name *</label>
        <!-- 通过Field插槽获取实时校验状态 -->
        <Field name="firstname" rules="required|firstname" v-slot="{ field, errors }">
            <input 
                id="firstNameId" 
                type="text" 
                v-bind="field"
                class="form-control" 
                :class="{ 'is-invalid': errors.length, 'is-valid': !errors.length && wasValidated }"
                placeholder="First Name" 
                aria-describedby="input-true input-false input-help" 
                :aria-invalid="errors.length > 0"
            />
        </Field>
        <!-- 错误信息直接绑定Bootstrap的invalid-feedback类 -->
        <ErrorMessage as="div" name="firstname" class="invalid-feedback" />
        <div class="valid-feedback">Good!</div>
    </div>
    <button type="submit" class="btn btn-primary mt-3">提交</button>
</Form>
</template>

<script>
import { Field, Form, ErrorMessage, defineRule } from 'vee-validate';

defineRule('required', value => {
    if (!value || !value.length) {
        return 'This field is required.';
    }
    return true;
});

defineRule("firstname", (value) => {
    if (!/^[a-zA-Z0-9( ),'.:/-]+$/i.test(value)) {
         return "Please use only letters, numbers and the following special characters: ( ),'.:/-";
    }
    return true;
});

export default {
    components: {
        Form,
        Field,
        ErrorMessage
    },
    data () {
        return {
             wasValidated: false
        }
    },
    methods: {
         async onFormSubmit(values, { validate }) {
              // 调用VeeValidate内置的全表单校验方法
              const { valid } = await validate();
              // 第一次提交就触发校验状态标记
              this.wasValidated = true;
              
              // 校验不通过直接终止逻辑
              if (!valid) return;
              
              // 校验通过后执行提交逻辑
              alert(JSON.stringify(values, null, 2));
              console.log("Submitted", values);
          }
    }
};
</script>

关键修改说明

  • 解决二次点击才触发校验的问题:删除了手动操作DOM绑定submit事件的冗余代码,直接在提交回调中调用VeeValidate内置的validate方法执行全表校验,同步更新wasValidated状态,第一次提交就能触发样式更新。
  • 解决反馈样式不生效的问题:
    • 通过Field组件的插槽获取实时校验状态,动态给input绑定is-invalid/is-valid类,匹配Bootstrap的样式触发规则
    • 把ErrorMessage的class直接设为invalid-feedback,和input保持同级,符合Bootstrap的DOM结构要求,校验失败时会自动渲染错误信息并触发样式
    • 动态绑定aria-invalid属性,替换原来的硬编码值,符合无障碍规范同时配合样式生效

如果你使用的是Bootstrap 5,只需要把模板里的form-group类替换为mb-3即可,其余逻辑完全兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:09:02