一、应用场景
表单校验在项目开发中是一个很常见的需求,通常在提交表单发起请求前校验用户输入是否符合规则,通常只需 formRef.value.validate() 即可校验,但是,例如一些多步骤表单、动态循环出的多个表单、以及不同的用户角色可能看到不同的表单内容,这些场景都需要在页面提交时需要对多个Form表单进行校验,多个表单校验成功之后才能进行下一步操作。
下面我就以动态循环出多个表单的校验方式进行举例;
注意:本案例需要动态设置Ref,具体实现请参考上篇文章 :
二、案例
-
最初效果:
-
输入过程中效果:包含 非空校验 与 输入范围校验
-
点击 ”提交“ 按钮效果
代码如下:(为了清晰明了,这里只展示表单部分)
这里的 selectData.infoCollectSelectVOS 是循环的表单,item.stuExtraAttrVOS 是每个表单中的数据项
<div
class="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-field
v-model="m.value"
:label="m.attrName"
colon
clearable
: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的同学可以看这篇文章,很细致哦~