在开发中遇到了这样一个需求
有一个
form
是通过v-for
生成出来的,并且数量不确定,每个表单中的字段都需要做校验,就将自己的解决方法记录了下来。
完整代码如下
html
<template>
<div class="for-form">
<el-button type="primary" @click="addHandle">新 增</el-button>
<div class="form-box">
<div class="form-item" v-for="(item, index) in formList" :key="index">
<el-form :model="item" :rules="rules" label-width="auto" style="max-width: 300px" label-position="top"
:ref="($event) => handle($event, index)">
<el-form-item label="名称" prop="name">
<el-input v-model="item.name" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="item.phone" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="item.sex">
<el-radio :value="1" size="small">男</el-radio>
<el-radio :value="2" size="small">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="爱好" prop="hobby" v-if="item.sex == 2">
<el-input v-model="item.hobby" placeholder="请输入爱好" />
</el-form-item>
</el-form>
</div>
</div>
<el-button type="primary" @click="saveHandle">保 存</el-button>
</div>
</template>
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
const state = reactive({
form: {} as any,
formList: [] as any,
rules: {
name: [
{ required: true, message: 'Please input Activity name', trigger: 'blur' },
],
},
formRefs: [] as any
})
const { formList, rules } = toRefs(state)
function addHandle() {
state.formList.push({
name: "",
phone: "",
sex: 1,
hobby: "",
})
}
function handle(e: any, index: any) {
// 保存下每个ref
state.formRefs[index] = e
}
async function saveHandle() {
let isSubmit: boolean[] = []
// 循环上面记录下来的ref对每个进行校验
for (const el of state.formRefs) {
await el.validate((valid: any) => {
// 每个 ref 校验成功或者失败都以布尔值存储下来
if (valid) {
isSubmit.push(true)
} else {
isSubmit.push(false)
}
})
}
// 只有当 isSubmit 存的值全是 true 时表示每个表单都校验成功了
// 然后就可以提交了
let has = isSubmit.every(i => i == true)
if (has) {
console.log("可以提交")
}
console.log(state.formRefs)
console.log(isSubmit)
}
</script>
<style scoped lang="scss">
.form-box {
display: flex;
align-items: flex-start;
.form-item {
margin-right: 20px;
}
}
</style>