VeeValidate required验证:b-form-input仅变更触发失焦不生效原因咨询
问题原因与解决方案
这个问题我之前帮不少开发者解决过,本质是原生HTML表单和Bootstrap Vue组件的校验触发逻辑差异导致的,具体来说:
- 原生
<input>的校验逻辑:浏览器原生的required校验是绑定在字段的blur事件上的——只要字段是必填且为空,不管你有没有修改过它,一旦失焦就会立刻触发校验并报错,这是浏览器内置的表单验证行为。 b-form-input的默认校验逻辑:Bootstrap Vue的这个组件是基于Vue响应式封装的,它默认的校验触发时机是字段值发生变更(input/change事件)。也就是说,如果你从未在这个字段里输入过内容,直接失焦的话,组件会认为“这个字段还没被用户触碰过”,不会主动触发必填校验;只有当你输入内容后再删除(字段从有值变为空,触发了变更事件),组件才会启动校验逻辑并报错。
解决办法
要让b-form-input和原生input保持一致的失焦校验行为,有几种简单的实现方式:
方式一:直接调用原生校验方法
给b-form-input绑定blur事件,调用底层原生input的checkValidity()方法,强制触发浏览器原生校验:
<b-form-input v-model="middlename" required @blur="$event.target.checkValidity()" ></b-form-input>
这种方式最直接,完全和原生input的校验行为对齐。
方式二:标记字段为“已触碰”
如果你在用Bootstrap Vue的表单验证体系(比如配合b-form和内置的校验状态),可以通过ref手动标记字段为touched(已触碰),组件会自动触发校验:
<b-form-input v-model="middlename" required @blur="() => $refs.middleInput.touched = true" ref="middleInput" ></b-form-input>
当字段被标记为touched且为空时,组件会立刻显示必填错误提示。
方式三:全局配置校验触发时机
如果你的项目里有大量b-form-input需要这个行为,可以全局配置组件的校验触发事件,一次性解决所有组件的问题:
import Vue from 'vue' import BootstrapVue from 'bootstrap-vue' Vue.use(BootstrapVue, { BFormInput: { validateOn: ['blur', 'input'] // 添加blur事件触发校验 } })
这样所有b-form-input组件都会在失焦和输入时自动触发校验,和原生input的行为一致。
内容的提问来源于stack exchange,提问作者Ashwini




