Elementui遍历多个表格校验

450 阅读1分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

在最近的项目开发中,遇到了一个需求,遍历出来的多个表单需要验证。其中每一个项是由一个下拉框和一个表格组成,表格的数据是可以输入的。需要验证格式和是否输入。下拉选择的项的内容是表格的一列。我们一起看看吧~

如图的效果: QQ图片20220215173908.png

需求分析

项目多选,项目选择完之后需要更新到对应的表格列中,表格列的名次和得分是输入的,新增项目的时候,新增一个新的遍历数据。单个表格数据可多选删除,单选删除,整体保存数据,整体回显数据。

一:遍历的数据格式

每一项由一个下拉框proIdstableData组成。

data() {
    return {
        pageList: [
            {
                proIds: [], // 下拉值 多选值
                tableData: [],// 表格数据
            }
        ],
        rules: {// 规则校验
            ranking : [
                { required: true, message: '名次不能为空'},
            ],
            score: [
                { required: true, message: '得分不能为空'},
            ],
        },
     }
}

二:html模板

整个遍历的表单表格代码如下:

<div v-for="(item, index) in pageList" :key="index">
    <div class="operate-box" ref="operateBox">
        <div class="operate-box-search">
            <el-form class="form-container" label-width="60px" style="margin-top: 10px" :disabled="isLook">
                <el-form-item label="项目:" prop="proIds">
                    <el-select filterable multiple v-model="item.proIds" placeholder="请选择项目" class="wid300" @change="choosePro(item)">
                        <el-option
                            v-for="item in projectList"
                            :value="item.id"
                            :key="item.id"
                            :label="item.name"></el-option>
                    </el-select>
                </el-form-item>
            </el-form>
        </div>
        <div class="operate-box-btn" v-if="!isLook">
            <el-button type="primary" size="mini" @click="newBtn(index)"><i class="el-icon-plus"></i> 添加</el-button>
            <el-button type="primary" size="mini" @click="deleteAll(index)">删除</el-button>
        </div>
    </div>
    <div class="my-table">
        <el-form :rules="rules" :model="item" :ref="'ruleForm'+index" class="demo-ruleForm" :disabled="isLook">
            <el-table
                ref="multipleTable"
                :data="item.tableData"
                :height="height"
                border
                resizable
                stripe
                @selection-change="handleSelectionChange">
                <el-table-column type="selection" align="center" fixed="left" width="55" v-if="!isLook"></el-table-column>
                <el-table-column label="序号" :index="getIndexNumber" type="index" align="center" width="80" fixed="left"></el-table-column>
                <el-table-column label="组别代码" prop="gnum" show-overflow-tooltip></el-table-column>
                <el-table-column label="组别" prop="gname" show-overflow-tooltip></el-table-column>
                <el-table-column label="项目名称" prop="proName" show-overflow-tooltip min-width="130"></el-table-column>
                <el-table-column prop="ranking" label="名次" align="center" width="180">
                    <template slot-scope="scope">
                        <template v-if="scope.row.isEdit">
                            <el-form-item :prop="'tableData.' + scope.$index + '.ranking'" :rules="rules.ranking" class="inline">
                                <el-input onkeyup="value=value.replace(/[^\d]/g,'')"  min="0" v-model="scope.row.ranking" placeholder="得分" class="wid150"></el-input>
                            </el-form-item>
                        </template>
                        <template v-else>
                            {{scope.row.ranking}}
                        </template>
                    </template>
                </el-table-column>
                <el-table-column prop="score" label="得分" align="center" width="180">
                    <template slot-scope="scope">
                        <template v-if="scope.row.isEdit">
                            <el-form-item :prop="'tableData.' + scope.$index + '.score'" :rules="rules.score" class="inline">
                                <el-input onkeyup="value=value.replace(/^\D*(\d*(?:.\d{0,1})?).*$/g, '$1')" min="0"  v-model="scope.row.score" placeholder="成绩" class="wid150"></el-input>
                            </el-form-item>
                        </template>
                        <template v-else>
                            {{scope.row.score}}
                        </template>
                    </template>
                </el-table-column>
                <el-table-column label="操作" align="center" fixed="right" width="100" v-if="!isLook">
                <template slot-scope="scope">
                    <span class="opera-btn" @click="deleteOne(scope.$index, index)">删除</span>
                </template>
                </el-table-column>
                <template slot="empty">
                    <empty></empty>
                </template>
            </el-table>
        </el-form>
    </div>
</div>

三:数据处理

1.选择项目

选择项目,填充到每一行的表格数据中

// 选择项目
choosePro(info){
    let arr = [];
    if(info.proIds.length){
        this.projectList.forEach(item=>{
            info.proIds.forEach(self=>{
                if(item.id == self){
                    arr.push(item.name);
                }
            })
        })
        this.$set(info,'proName',arr.join('、'));// 选择项目的名字
        if(info.tableData.length){
            info.tableData.forEach(item=>{
                this.$set(item,'proName',arr.join('、'));// 选择完项目之后,填充到没一行表格数据中
            })
        }
    }else{
      info.tableData = [];
    }
},

2. 添加项目 新增一个遍历的对象

新增一个可遍历的对象数据

// 添加项目 新增一个遍历的对象
addNewProject(){
    this.pageList.push({
        proIds: [],
        tableData: [],
    })
},

3.单个表格数据删除 根据 index删除

单个表格数据根据index进行删除

// 单个表格数据删除 根据 index删除
deleteOne(index,i) {
    this.pageList[i].tableData.forEach((item, j)=>{
        if(index == j){
            this.pageList[i].tableData.splice(j, 1);
        }
    })
},

4.批量删除数据

将选中的表格的部分数据统一删除

// 批量删除
onDelete(rowIds, index){
    for(let i = 0;i < rowIds.length;i++){
        for(let j = 0;j < this.pageList[index].tableData.length;j++){
            if(j == rowIds[i]){
                this.pageList[index].tableData.splice(j,1);
                j--;
            }
        }
    }
},

5.新增表格行

在对应的表格下面新增一行表格数据。

// 新增表格行
newBtn(index) {
    if(this.pageList[index].proIds.length){
        this.pageList[index].tableData.push({
            gnum: this.gnum,
            gname: this.gname,
            isEdit: true,
            score: '0',
            ranking: '0',
            proName: this.pageList[index].proName
        })
    }else{
        this.$message({
            message: '请先选择项目',
            type: 'error'
        });
    }
},

6.保存数据

ref的名字是动态生成的,遍历的时候需要循环遍历,判空保存。

// 保存数据
saveForm() {
    let flag = 0, newFlag = 0;
    if(this.pageList.length > 0){
        this.pageList.forEach(item=>{
            if(item.tableData.length == 0){
                flag = 1;
            }
        })
        if(flag == 0){
            this.pageList.forEach((item, i)=>{
                this.$refs[("ruleForm" + i)][0].validate(valid => {
                    if (valid) {// 通过验证
                        newFlag++;
                    } else {// 失败
                        return false;
                    }
                });
            })
            if(newFlag == this.pageList.length){
                this.onSubmit(); // 接口保存
            }
        }
    }else{
        this.$message({
            message: '请先新增数据',
            type: 'error'
        });
    }
},

以上就是遍历多个表格校验的全部代码了,希望怼你有帮助~