使用 Vee-validate 禁用按钮,直到正确填写表单
Using Vee-validate to disable button until form is filled out correctly
我想禁用我的提交按钮,直到我的表单填写正确,这是我目前拥有的:
<form>
<input type="text" class="form-control" v-validate="'required|email'" name="email" placeholder="Email" v-model="userCreate.userPrincipalName" />
<span v-show="errors.has('email')">{{ errors.first('email') }}</span>
<button v-if="errors.any()" disabled="disabled" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>
<button v-else="errors.any()" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>
</form>
在我开始输入值后,以上仅打印一条错误消息并禁用我的提交按钮。在开始与输入交互之前,我需要从一开始就禁用它,这样我就无法发送空字符串。
另一个问题是,是否有比使用 v-if
更好的方法来做到这一点?
编辑:
userCreate: {
customerId: null,
userPrincipalName: '',
name: 'unknown',
isAdmin: false,
isGlobalAdmin: false,
parkIds: []
}
在您需要的所有值都被填充之前禁用按钮的一种方法是使用计算 属性 如果所有值都已分配或未分配,它将 return bool
示例:
像这样创建计算 属性:
computed: {
isComplete () {
return this.username && this.password && this.email;
}
}
并将其绑定到 html disabled
属性为:
<button :disabled='!isComplete'>Send Invite</button
这意味着,如果 !isComplete
为 true
,则禁用该按钮
此外,在您的情况下,您不需要两个 if/else-bound 按钮。您可以只使用一个 hide/show 它取决于表格是否已完成 或 是否有任何错误:
<button :disabled="errors.any() || !isCompleted" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>
在填写所有字段且未发现错误之前,此按钮将被禁用
或使用计算
computed: {
formValidated() {
return Object.keys(this.fields).some(key => this.fields[key].validated) && Object.keys(this.fields).some(key => this.fields[key].valid);
}
}
并使用
button :disabled="!formValidated" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">
另一种方法是使用 v-validate。initial
<input type="text" class="form-control" v-validate.initial="'required|email'" name="email" placeholder="Email" v-model="userCreate.userPrincipalName" />
这将在页面加载后执行电子邮件输入元素的验证。并使您的按钮在与输入交互之前被禁用。
要检查表单是否无效,我们可以像这样添加 computed
属性:
computed: {
isFormInValid() {
return Object.keys(this.fields).some(key => this.fields[key].invalid);
},
},
现在,如果您想在用户与任何字段交互之前立即开始检查,您可以在 mounted
生命周期挂钩中手动验证:
mounted() {
this.$validator.validate();
}
将按钮设置为 :disabled:"errors.any()"
会在 验证后 禁用按钮。但是,当组件首次加载时,它仍将处于启用状态。
运行 this.$validator.validate()
在 mounted()
方法中,正如@im_tsm 所建议的那样,导致表单在启动时进行验证并立即显示错误消息。该解决方案将导致表单看起来非常难看。此外,Object.keys(this.fields).some(key => this.fields[key].invalid);
语法超级难看。
相反,运行 验证器在单击按钮时获取 promise 中的有效性,然后在条件中使用它。使用此解决方案,表单在启动时看起来很干净,但如果他们单击按钮,它将显示错误并禁用按钮。
<button :disabled="errors.any()" v-on:click="sendInvite();">
Send Invite
</button>
sendInvite() {
this.$validator.validate().then(valid=> {
if (valid) {
...
}
})
}
可能最简单的方法是对表单使用 ValidationObserver
插槽。像这样:
<ValidationObserver v-slot="{ invalid }">
<form @submit.prevent="submit">
<InputWithValidation rules="required" v-model="first" :error-messages="errors" />
<InputWithValidation rules="required" v-model="second" :error-messages="errors" />
<v-btn :disabled="invalid">Submit</v-btn>
</form>
</ValidationObserver>
更多信息 - Validation Observer
对于当前版本 3(截至撰写本文时)。
步骤 1
确保可以查看表单字段。
第 2 步
获取对验证器实例的引用:
<ValidationObserver ref="validator">
.
步骤 3
每当表单字段更改时触发验证silently。
这是一个例子:
export default {
data() {
return {
form: {
isValid: false,
fields: {
name: '',
phone: '',
}
}
}
},
watch: {
'form.fields': {
deep: true,
handler: function() {
this.updateFormValidity();
}
}
},
methods: {
async updateFormValidity() {
this.form.isValid = await this.$refs.validator.validate({
silent: true // Validate silently and don't cause observer errors to be updated. We only need true/false. No side effects.
});
},
}
}
<button :disabled="form.isValid">
Submit
</button>
您可以添加计算属性
...
computed: {
isFormValid () {
return Object.values(this.fields).every(({valid}) => valid)
}
}
...
并绑定到按钮:
<button :disabled="!isFormValid" class="btn btn-primary" type="submit">Send Invite</button>
我在 vee-validate 版本 ^2.0.3 上试试这个
我想禁用我的提交按钮,直到我的表单填写正确,这是我目前拥有的:
<form>
<input type="text" class="form-control" v-validate="'required|email'" name="email" placeholder="Email" v-model="userCreate.userPrincipalName" />
<span v-show="errors.has('email')">{{ errors.first('email') }}</span>
<button v-if="errors.any()" disabled="disabled" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>
<button v-else="errors.any()" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>
</form>
在我开始输入值后,以上仅打印一条错误消息并禁用我的提交按钮。在开始与输入交互之前,我需要从一开始就禁用它,这样我就无法发送空字符串。
另一个问题是,是否有比使用 v-if
更好的方法来做到这一点?
编辑:
userCreate: {
customerId: null,
userPrincipalName: '',
name: 'unknown',
isAdmin: false,
isGlobalAdmin: false,
parkIds: []
}
在您需要的所有值都被填充之前禁用按钮的一种方法是使用计算 属性 如果所有值都已分配或未分配,它将 return bool
示例:
像这样创建计算 属性:
computed: {
isComplete () {
return this.username && this.password && this.email;
}
}
并将其绑定到 html disabled
属性为:
<button :disabled='!isComplete'>Send Invite</button
这意味着,如果 !isComplete
为 true
此外,在您的情况下,您不需要两个 if/else-bound 按钮。您可以只使用一个 hide/show 它取决于表格是否已完成 或 是否有任何错误:
<button :disabled="errors.any() || !isCompleted" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">Send Invite</button>
在填写所有字段且未发现错误之前,此按钮将被禁用
或使用计算
computed: {
formValidated() {
return Object.keys(this.fields).some(key => this.fields[key].validated) && Object.keys(this.fields).some(key => this.fields[key].valid);
}
}
并使用
button :disabled="!formValidated" class="btn btn-primary" v-on:click="sendInvite();" data-dismiss="modal" type="submit">
另一种方法是使用 v-validate。initial
<input type="text" class="form-control" v-validate.initial="'required|email'" name="email" placeholder="Email" v-model="userCreate.userPrincipalName" />
这将在页面加载后执行电子邮件输入元素的验证。并使您的按钮在与输入交互之前被禁用。
要检查表单是否无效,我们可以像这样添加 computed
属性:
computed: {
isFormInValid() {
return Object.keys(this.fields).some(key => this.fields[key].invalid);
},
},
现在,如果您想在用户与任何字段交互之前立即开始检查,您可以在 mounted
生命周期挂钩中手动验证:
mounted() {
this.$validator.validate();
}
将按钮设置为 :disabled:"errors.any()"
会在 验证后 禁用按钮。但是,当组件首次加载时,它仍将处于启用状态。
运行 this.$validator.validate()
在 mounted()
方法中,正如@im_tsm 所建议的那样,导致表单在启动时进行验证并立即显示错误消息。该解决方案将导致表单看起来非常难看。此外,Object.keys(this.fields).some(key => this.fields[key].invalid);
语法超级难看。
相反,运行 验证器在单击按钮时获取 promise 中的有效性,然后在条件中使用它。使用此解决方案,表单在启动时看起来很干净,但如果他们单击按钮,它将显示错误并禁用按钮。
<button :disabled="errors.any()" v-on:click="sendInvite();">
Send Invite
</button>
sendInvite() {
this.$validator.validate().then(valid=> {
if (valid) {
...
}
})
}
可能最简单的方法是对表单使用 ValidationObserver
插槽。像这样:
<ValidationObserver v-slot="{ invalid }">
<form @submit.prevent="submit">
<InputWithValidation rules="required" v-model="first" :error-messages="errors" />
<InputWithValidation rules="required" v-model="second" :error-messages="errors" />
<v-btn :disabled="invalid">Submit</v-btn>
</form>
</ValidationObserver>
更多信息 - Validation Observer
对于当前版本 3(截至撰写本文时)。
步骤 1
确保可以查看表单字段。
第 2 步
获取对验证器实例的引用:
<ValidationObserver ref="validator">
.
步骤 3
每当表单字段更改时触发验证silently。
这是一个例子:
export default {
data() {
return {
form: {
isValid: false,
fields: {
name: '',
phone: '',
}
}
}
},
watch: {
'form.fields': {
deep: true,
handler: function() {
this.updateFormValidity();
}
}
},
methods: {
async updateFormValidity() {
this.form.isValid = await this.$refs.validator.validate({
silent: true // Validate silently and don't cause observer errors to be updated. We only need true/false. No side effects.
});
},
}
}
<button :disabled="form.isValid">
Submit
</button>
您可以添加计算属性
...
computed: {
isFormValid () {
return Object.values(this.fields).every(({valid}) => valid)
}
}
...
并绑定到按钮:
<button :disabled="!isFormValid" class="btn btn-primary" type="submit">Send Invite</button>
我在 vee-validate 版本 ^2.0.3 上试试这个