setCustomValidity仅在第二次单击时应用



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

if (
this.registration.user.password !==
this.registration.user.password_confirmation
) {
console.log('check')
document
.getElementById('password_confirmation')
.setCustomValidity('Passwords do not match')
}

此逻辑位于<form ... @submit="registerUser">中出现的registerUser方法内部。我注意到,当我在两个密码不相等的情况下点击提交按钮时,第一次什么都没有发生,但在日志中我仍然可以看到打印的"检查"。第二次单击提交按钮时,我收到了验证错误。

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

编辑:

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

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

我的checkConfirmation方法就是这样:

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('')",否则,如果您输入了不正确的输入并进行了修复,错误将不会消失
  • 上面的方法仍然不是防弹的——如果用户没有输入有效的(如果它是预先填充的(,那么验证就会通过。这适用于模式检查和更改验证

EDIT:好吧,一种更简单的编写方法是如下(如果最终目标是检查2个字段的相等性(:

<template>
<div>
<form @submit.prevent="checkPasswordFields">
<input v-model="password" placeholder="input password" />
<input v-model="passwordConfirmation" placeholder="confirm password" />
<button>submit</button>
</form>
<p>do password match ? >> {{ doPasswordMatch }}</p>
</div>
</template>
<script>
export default {
data() {
return {
password: '',
passwordConfirmation: '',
}
},
methods: {
checkPasswordFields() {
console.log(`Password do${this.doPasswordMatch ? '' : ' not'} match !`)
},
},
computed: {
doPasswordMatch() {
return this.password === this.passwordConfirmation
},
},
}
</script>

这可能是因为DOM在传递到setCustomValidity方法之前没有重新渲染。根据你的情况,Vue可能还没有更新它的状态。

首先,您应该将document.getElementById切换为$refs,如下所述:https://v2.vuejs.org/v2/guide/components-edge-cases.html#Accessing-子组件实例和子元素

所以,它可能看起来像

<base-input ref="passwordConfirmation"></base-input>

然后,你用选择你的元素

this.$refs.passwordConfirmation

仅凭这一点,也许就能解决问题。


如果不够,还可以挤压

await this.$nextTick()

在你的病情之前。这样,您将等待Vue更新其状态,然后再继续。

当然,在不依赖nextTick破解的情况下,可能有一种更常见的方法可以做到这一点,但这一切都取决于您的代码逻辑,我们需要更多。

一个很好的干净的替代方案是使用包vee-validate,它将帮助您进行更简洁、结构更好的前端验证:https://vee-validate.logaretm.com/v3/guide/rules.html#confirmed


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

相关内容

  • 没有找到相关文章