Javascript setCustomValidity仅在第二次单击时应用

Javascript setCustomValidity仅在第二次单击时应用,javascript,vue.js,validation,Javascript,Vue.js,Validation,我有一个Vue应用程序,其中我有以下逻辑: if ( this.registration.user.password !== this.registration.user.password_confirmation ) { console.log('check') document .getElementById('password_confirmation') .setCustomValidity

我有一个Vue应用程序,其中我有以下逻辑:

if (
     this.registration.user.password !==
     this.registration.user.password_confirmation
   ) {
        console.log('check')
        document
          .getElementById('password_confirmation')
          .setCustomValidity('Passwords do not match')
      }
此逻辑位于中出现的registerUser方法中。我注意到,当我在两个密码不相等的情况下单击submit按钮时,第一次什么也没有发生,但在日志中我仍然可以看到“check”打印出来。第二次单击submit按钮时,出现验证错误

有人知道这里出了什么问题吗?为什么第二次出现这个音符

编辑:

我想我已经解决了。问题是我在registerUser方法中设置了验证,这是在单击发生后触发的,因此通过表单模式阻止验证已经太晚了。我通过专门在@onchange调用中调用密码检查器修复了它,如下所示:

<input
        ref="password_confirmation"
        v-model="registration.user.password_confirmation"
        type="password"
        placeholder="Repeat password..."
        required
        oninput="setCustomValidity('')"
        @change="checkConfirmation"
      />
一些重要的注意事项:

您需要oninput=setCustomValidity,否则,如果您输入了错误的输入,然后对其进行修复,错误将不会消失 上述方法仍然不是防弹的-如果用户没有输入有效的,如果它已预填充,则验证将通过。这适用于模式检查和更改验证。
编辑:好的,如果最终目标是检查两个字段的相等性,则编写内容的更简单方法如下:

提交 密码匹配吗?>>{{doPasswordMatch}

导出默认值{ 资料{ 返回{ 密码:, 密码确认:, } }, 方法:{ checkPasswordFields{ console.log`Password do${this.doPasswordMatch?:'not'}匹配` }, }, 计算:{ doPasswordMatch{ 返回this.password==this.passwordConfirmation }, }, } 这可能是因为DOM在传递到setCustomValidity方法之前没有重新呈现。根据您的情况,Vue可能尚未更新其状态

首先,您应该将document.getElementById切换为$refs,如下所述:

所以,它可能看起来像

然后,使用

此.$refs.passwordConfirmation 仅此一项,就可能解决问题

如果还不够,你也可以挤一杯

等着吧,下一个 在你生病之前。这样,您将等待Vue更新其状态,然后再继续

当然,可能有一种不依赖nextTick hack的更为常见的方法,但这一切都归结于您的代码逻辑,我们将需要更多

一个好的干净替代方案是使用vee validate软件包,它将帮助您进行更简洁、结构更好的前端验证:


回答问题的最后一部分:第二次确实会发生,因为Vue在第二次运行时更新了状态。

嘿,谢谢你的回答!不幸的是,使用refs和nextTick没有帮助,我仍然在第二次单击时收到验证错误。我们需要一些代码,或者至少需要更多代码才能继续。一些vue devtools调试结果也很有用!很抱歉耽误了回来的时间,但我想我已经解决了,尽管还有一些悬而未决的问题。请参阅我更新的问题描述,以更新答案,但它仍然无法修复原始问题。正如我在问题中所解释的,问题在于验证只在第二次单击时发生,解决方法是在表单字段中使用@change并将其链接到设置自定义有效性的函数。为了处理预填充的值,我使用了类似于vee-validate的vuelidate。很高兴我提供了帮助。是的,最后,你可以用几种方法来做!oninput不存在,正确的是@input。您可能应该抛出@change+@输入,并将其替换为带有immediate:true的手表registration.user.password\u confirmation。此外,您可能会将v-model替换为:value+@输入,因为在本例中它只是一种糖类语法。这样,你也可以去掉ref。好吧,你基本上可以忽略我上面写的内容,检查我更新的答案,这将给你一个超级简单的方法来检查两个字段的有效性相等。这是有效的,因为计算属性不需要太多代码,如果您有预填充值,它应该完全可以工作。如果您的目标是更复杂、更灵活的验证,我仍然可以大力推荐。
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'
        )
      }
    }