Vuelidate异步自定义验证未等Promise完成即通过,如何修正?
解决方案
要解决异步验证完成前按钮误启用的问题,核心是利用Vuelidate的异步验证状态,在请求pending阶段保持提交按钮禁用,具体修改如下:
1. 完善邮箱异步验证规则
补充完整的验证规则,确保异步验证函数正确返回Promise,让Vuelidate自动跟踪验证状态:
import { ref } from 'vue' import { useVuelidate } from '@vuelidate/core' import { required, email, helpers } from '@vuelidate/validators' import { checkEmail } from '@/utils/validators' // 表单数据(假设form已定义,包含email字段) const form = ref({ email: '' }) // 邮箱验证规则 const rules = { email: { required: helpers.withMessage('邮箱不能为空', required), email: helpers.withMessage('请输入有效的邮箱格式', email), // 异步检查邮箱是否已注册 isUnregistered: helpers.withMessage('该邮箱已被注册', async (emailValue) => { // 先跳过空值或格式错误的情况,交给前面的验证规则处理 if (!emailValue || !email(emailValue)) return true // 调用后端验证接口,checkEmail需返回:未注册返回true,已注册返回false return await checkEmail(emailValue) }) } } const v$ = useVuelidate(rules, form)
2. 控制提交按钮禁用状态
修改提交按钮的禁用条件,除了表单验证不通过(v$.$invalid),还要加上邮箱验证的pending状态(v$.email.$pending),确保请求未完成时按钮保持禁用:
<template> <Input id="invite-email" name="invite-email" class="w-full" :errors="v$.email.$errors" v-model="v$.email.$model" :invitePlayer="true" > {{ t('placeholder.email') }} </Input> <!-- 提交按钮 --> <button @click="invite" :disabled="v$.$invalid || v$.email.$pending" :class="{ 'opacity-50 cursor-not-allowed': v$.$invalid || v$.email.$pending }" > {{ v$.email.$pending ? '验证中...' : '发送邀请' }} </button> </template>
3. 关键逻辑说明
- Vuelidate会自动跟踪异步验证的状态:当
isUnregistered的Promise处于pending时,v$.email.$pending会变为true,此时按钮保持禁用。 - 确保
checkEmail函数返回值符合预期:邮箱未注册返回true(验证通过),已注册返回false(验证失败,触发错误提示)。 - 按钮文本可根据
$pending状态动态切换,给用户明确的加载反馈。
内容的提问来源于stack exchange,提问作者Tomas Gil Amoedo
相关产品推荐
相关产品推荐

