vue3+setup 多个表单使用同一校验规则 ,点击按钮时一起校验
前言
根据接口获取到的数据,在弹出框展示,数据是数组格式,需要for循环,展示形式是表单form,需要对表单进行修改,验证。
一、一个表单下的for循环
因为页面展示很简单,就一个搜索下拉框,加几个选择下拉框,然后循环一下就好了;功能很简单,就是选择就行了;验证就更简单,只验证一个搜索下拉框就行。所以我直接在form下for循环,但问题很快出现:因为form的prop不支持同一个,后来又改成给每条数据添加一个新参数(就是旧的参数加了个索引。如旧参数是 value,现在是value0)但是后面发现还是不能验证。 百度了一下,说是 v-model="v[sectionSort${i}
]"这里的问题,v-module的参数和prop的参数不匹配
代码如下:
<el-form :ref="formRef" :model="workLineList">
<div v-for="(v, i) in workLineList" :key="i" style="margin-bottom: 20px">
<el-form-item
label="名称:"
:prop="'sectionSort'+i"
:rules="[{ required: true, trigger: 'blur', message: '请选择' }]"
style="float: left; margin-left: 40px"
>
<el-select
v-model="v[`sectionSort${i}`]"
clearable
filterable
:loading="loading"
placeholder="请选择"
remote
:remote-method="createRemoteMethod(v, i)"
style="width: 220px"
>
<el-option
v-for="item in v.opina"
:key="item.productionLineId"
:label="item.productionLineName"
:value="item.productionLineName"
/>
</el-select>
</el-form-item>
</div>
</el-form>
二、多个表单循环
后面没办法了,既然单表单用不了,就上多表单。
代码如下(示例):
<script setup>
const lineFormRef = ref([]) // 存储表单引用的数组
const workLineDialog = ref(false)
const loading = ref(false)
const workLineList = ref([])
const getData = (row) => {
let data = {}
getData(data).then((res) => {
res.data.forEach((v, i) => {
// 存储数据和初始为 null 的引用
workLineList.value.push({ data: v, ref: ref(null) })
lineFormRef.value.push(`formRef${i}`) // 存储引用名
})
})
}
const workLineClose = () => {
workLineDialog.value = false
lineFormRef.value.forEach((formRef) => {
if (formRef && formRef.resetFields) {
formRef.resetFields() // 调用 resetFields 方法重置表单
}
})
}
const worklineAdSubmit = async () => {
const validationPromises = lineFormRef.value.map((formRef) => {
if (formRef && formRef.validate) {
return formRef.validate()
}
return Promise.resolve(true) // 如果没有表单或验证函数,则直接返回已解决的 Promise
})
try {
const valid = await Promise.all(validationPromises)
console.log(valid) // [true,true]
if (valid.every((result) => result === true)) {
// 走后续的代码
submitData()
}
} catch {
/**
* 执行校验失败抛出异常的逻辑
*/
}
}
function submitData() {
}
</script>
<template>
<div class="goods-comment-container auto-height-container">
<el-dialog v-model="workLineDialog" :close-on-click-modal="false" draggable title="标题" width="800px" @close="workLineClose">
<div v-for="(v, i) in workLineList" :key="i" style="margin-bottom: 20px">
<el-form :ref="(el) => (lineFormRef[i] = el)" :model="v">
<el-form-item
label="名称:"
prop="sectionSort"
:rules="[{ required: true, trigger: 'blur', message: '请选择' }]"
style="float: left; margin-left: 40px"
>
<el-select
v-model="v.sectionSort"
clearable
filterable
:loading="loading"
placeholder="请选择"
remote
:remote-method="createRemoteMethod(v, i)"
style="width: 220px"
>
<el-option
v-for="item in v.opina"
:key="item.productionLineId"
:label="item.productionLineName"
:value="item.productionLineName"
/>
</el-select>
</el-form-item>
</el-form>
</div>
<el-form>
<el-form-item style="flex-direction: column; align-items: center; margin-top: 20px">
<el-button v-preventReClick type="primary" @click="worklineAdSubmit">保存</el-button>
<el-button @click="workLineClose">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
这段代码是我的源代码,改了一下直接贴上去了,可能有些地方少了或是多了。
我先讲一下思路:
获取到数据以后呢,通过lineFormRef ,workLineList这两参数把 html里面的表单 ref给ref(null)了,因为vue3 和2不一样,vue2的话不需要 在js 进行ref 直接 this.$ref.lineFormRef 这样就行,vue3不行,所以这也是单form时的一个问题。这样在得到form的ref名称以及对formref以后,html就可以循环form表单,然后再走保存,取消功能。
保存功能:因为是多表单,所以保存的时候要对多表单同时做验证,这时就要用Promise.all方法了。先循环数组,然后拿到表单的validate ,再把validate 数组放进Promise.all方法。这个保存验证功能基本就是实现了
取消功能;同上,就是把validate 变成resetFields,然后也不需要Promise.all方法
思路大概就是这样,我也是百度以后学的。
2.问题
功能验证是没问题了,但是现在又发现表单验证有问题,就是表单不会自动暴露问题,比如我清空数据,按理说表单会自动爆红,但是它没有,只有点击按钮功能,才会爆红。这里后面再看看咋解决
总结
vue3 和 vue2 不同之处还是蛮大的,还要再学习。然后表单验证这一块还是不能图省事,该表单循环还是要循环的。先就这样,后面问题解决了再写。