我有一个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在第二轮运行时更新了状态。