一、应用场景
表单校验在项目开发中是一个很常见的需求,通常在提交表单发起请求前校验用户输入是否符合规则,通常只需 formRef.value.validate() 即可校验,但是,例如一些多步骤表单、动态循环出的多个表单、以及不同的用户角色可能看到不同的表单内容,这些场景都需要在页面提交时需要对多个Form表单进行校验,多个表单校验成功之后才能进行下一步操作。
下面我就以动态循环出多个表单的校验方式进行举例;
注意:本案例需要动态设置Ref,具体实现请参考上篇文章 :
vue3项目中如何动态循环设置ref并获取使用
二、案例
-
最初效果:
-
输入过程中效果:包含 非空校验 与 输入范围校验
-
点击 ”提交“ 按钮效果
代码如下:(为了清晰明了,这里只展示表单部分)
这里的 selectData.infoCollectSelectVOS 是循环的表单,item.stuExtraAttrVOS 是每个表单中的数据项
<divclass="mb-4 bg-white rounded-md"v-for="(item, index) in selectData.infoCollectSelectVOS":key="index"><van-form :ref="setItemRef"><van-cell-group inset><template v-for="m in item.stuExtraAttrVOS" :key="m.id"><van-fieldv-model="m.value":label="m.attrName"colonclearable:placeholder="`请输入${m.min >= 0 ? m.min : ''}${m.min >= 0 ? '~' : ''}${m.max >= 0 ? m.max : ''}`":rules="[{ required: true, message: `请输入${m.attrName}` },{validator: () => {return checkValue(m)},message: `输入范围在${m.min} ~ ${m.max}`,},]"><template #button>{{ m.unit }}</template></van-field></template></van-cell-group></van-form></div><button @click="onSubmit">提交</button>
- 自定义输入范围校验代码:
// 表单自定义输入范围校验规则
const checkValue = (item: any) => {if ((item.value &&item.max >= 0 &&item.min >= 0 &&Number(item.value) > Number(item.max)) ||Number(item.value) < Number(item.min)) {return false} else {return true}
}
- 动态获取循环form表单的Ref代码
const refList = ref<any>([])
const refListValid = ref<any>([])
const setItemRef = (el: any) => {if (el) {refList.value.push(el)}
}
- 点击"提交"执行的代码
// 点击 提交按钮
const onSubmit = async () => {if (!admissionCard.value) {showToast('准考证号不能为空!')return}try {refListValid.value = []for (let i = 0; i < refList.value.length; i++) {refListValid.value.push(refList.value[i].validate())}console.log('refListValid.value :>> ', refListValid.value)Promise.all(refListValid.value).then(() => {// 所有表单成功后执行的代码// 比如请求提交接口...})} catch (error) {console.log('error :>> ', error)}
}
总结:解释为什么这里使用 Promise.all() 而不使用 async / await 原因
async await / Promise.all()
在 Vue 3 中使用 FormRef.value.validate() 方法返回的可能是一个 Promise;这是因为许多表单验证库(如 Vant 或 Element Plus 等)在进行异步验证时会返回 Promise 以便处理异步操作。在这种情况下,validate() 方法会返回一个 Promise,而不是直接返回一个布尔值。【Promise<pending>,Promise<pending>】
1、async await
优点:
- 可以分段校验,当第一个表单校验失败后,不会继续校验第二个表单,可在特定逻辑中使用;
- 可以使用try catch捕获错误,执行错误后的逻辑;
缺点:
- 执行按照代码逻辑顺序依次校验;
- 当出现校验失败时立刻停止,不再校验未校验的表单,会出现校验提示显示不全问题;
2、Promise.all()
优点:
- 可以使用try catch捕获错误,执行错误后的逻辑;
- 同时校验多个表单,即便其中一个表单校验错误,抛出异常,仍会校验所有表单,用于这种产场景页面表现效果更为理想;
以上便是 “基于Vue3+vant4 实现多表单提交校验” 的全部内容,希望对大家有所帮助~如果大家有任何疑问及指正,欢迎评论指出~
本文章借鉴与 基于Vue3+Element Plus 实现多表单校验demo_vue.js_脚本之家 使用Element Plus的同学可以看这篇文章,很细致哦~