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

Vue表单中setCustomValidity仅在第二次点击提交时生效的问题排查与解决

问题原因解析

嘿,这个问题我之前也踩过坑!核心原因是表单原生验证的时机早于你在@submit里执行的自定义校验:

当你点击提交按钮时,浏览器会先触发自身的原生表单验证流程(比如检查必填项、格式是否合法),只有当原生验证通过后,才会执行你绑定的registerUser方法。第一次点击时,你的setCustomValidity还没来得及给输入框设置错误信息,原生验证自然不会识别到这个错误;等第一次点击后,错误信息已经被设置,第二次提交时,浏览器的原生验证就会读取到这个错误,才会弹出提示。

简单来说:你的校验代码跑慢了一步,赶不上第一次的原生验证流程,第二次才“赶得上”。

已验证的解决方案:提前触发校验

你已经找到的把校验逻辑移到@change事件里的方案完全正确,这里再把细节和补充优化点整理清楚:

1. 模板代码调整

给密码确认输入框绑定@change事件,同时必须加上oninput="setCustomValidity('')":

<input 
  ref="password_confirmation" 
  v-model="registration.user.password_confirmation" 
  type="password" 
  placeholder="Repeat password..." 
  required 
  oninput="setCustomValidity('')" 
  @change="checkConfirmation" 
/>

2. 校验方法实现

在Vue组件的methods中编写校验逻辑,实时对比两次密码:

checkConfirmation() {
  const form = this.registration.user
  if (form.password === form.password_confirmation) {
    this.$refs.password_confirmation.setCustomValidity('')
  } else {
    this.$refs.password_confirmation.setCustomValidity(
      'Passwords do not match'
    )
  }
}

关键注意事项

  • 务必添加oninput="setCustomValidity('')":如果省略这一步,当用户输入错误密码后再修正,浏览器会保留之前设置的错误信息,不会自动清除,导致验证提示一直挂着,影响体验。
  • 补充优化:覆盖预填充场景:你提到的“用户未手动输入(如预填充)时校验不触发”的问题,可以通过监听原始密码字段的变化来解决,添加一个watch:
watch: {
  'registration.user.password': function() {
    // 当原始密码变化时,自动触发确认密码校验
    this.checkConfirmation()
  }
}

这样不管是用户手动修改密码,还是浏览器预填充密码,都能触发一致性校验,覆盖更多场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:27:28