循环动态form的校验,简单记录一下

206 阅读1分钟

问题场景: 一个新增页面:(基础信息表单,一个数据列表的表单),数据列表里面的表单数是动态添加的。数据结构大概是这样:

const params = {
    userInfo: {
        name: 'tom',
        address: '*****',
    },
    members: [
        {
            relationship: '1',
            name: 'tony',
            phones: [
                {
                    ···
                }
            ]
        },
        {
            relationship: '2',
            ····
        },
   ]
}

这个members是动态添加的表单,name为必填项需要做校验。 最开始的思路是定义一个form的列表,加一个member就往里面添加一个表单对象。提交时循环form列表用validate()进行校验,但是会出现一个问题就是添加的表单对象并没有绑定dom。

<template>
    <div>···</div>
    <div v-for="(item, index) in state.memberInfo" :key="index">
        <el-form 
            :model="state.memberInfo[index].form"
            :ref="`form${index}`"
        >
        ····
        </el-form>
    </div>
    <div @click="handleAddItemClick">添加Member</div>
    
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
    form0: null, // 默认有一个,可以继续新增
    memberInfo: [
        { 
            form: {....},
            ...
        }
    ]
})
// 添加一个表单到列表
const handleAddItemClick = () => {
    // 这里新定义的form1 或者form2是获取不到绑定的ref
    state[`form${state.memberInfo.length}`] = null
    state.memberInfo.push({...})
}
// 提交表单
const submit = () => {
    try {
        // 因为动态添加的form是没有绑定上ref的,这里会报错
        const validList = state.memberInfo.map((item,index)=> {
            return state[`form${index}`].validForm()
        })
        Promise.all(validList).then(res => {
               ···
        }).catch(err => {
            ···
        })
    }.catch( err => {
        ···
    })
}
</script>

翻了一下文档发现ref 可以接收一个函数值,用于对存储引用位置的完全控制。

<el-form 
    // 这样能成功获取到节点
    :ref="el => state[`form${index}`] = el"
>

最后还有一种最简单的方法,直接写固定的ref。不管用多少次都可以获取到所有绑定的节点。

<el-form
    ref="formList"
>
<script setup>
import { ref } from 'vue'
// formList会存储所有ref为'formList'的实例
const formList = ref(null)

有其他更好的方法可以指导一下,一起学习一起进步~