1、不分页表格表单校验
1、表格外面套一个form表单来实现批量校验
<el-form style="margin-top:0" ref="taskRef" :rules="rulesTask" :model="taskForm">
<el-table :key="activeName" :data="detailTableData" border :header-cell-style="{ background: '#fff' }">
<el-table-column align="center" type="index" width="80" label="序号"></el-table-column>
<el-table-column align="center" prop="itemNum" label="子目号"></el-table-column>
<el-table-column align="center" prop="itemName" label="子目名称"></el-table-column>
<el-table-column align="center" prop="units" label="单位"></el-table-column>
<el-table-column align="center" prop="quantity" label="数量"></el-table-column>
<el-table-column v-if="activeName !== 'first'" align="center" prop="quantityAfterChange" label="变更后的数量合计"></el-table-column>
<el-table-column align="center" prop="price" label="单价(元)"></el-table-column>
<el-table-column align="center" prop="amount" label="合价(元)"></el-table-column>
<el-table-column v-if="activeName=='first'" align="center" prop="temporaryPrice" label="暂计量单价(元)">
<template slot-scope="{row,$index}">
<span v-if="handleType=='view'||!row.editable">{{row.temporaryPrice}}</span>
<el-form-item v-else :prop="'taskData.' + $index + '.temporaryPrice'" :rules="temporaryPriceRules(row,$index)">
<el-input-number
clearable
style="width:120px"
v-model="row.temporaryPrice"
:max="999999.99"
:min="0"
:precision="2"
:controls="false"
size="mini"
placeholder="请输入"
@change="priceChange(row,$index)"
></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column v-if="activeName=='first'" align="center" prop="temporaryAmount" label="暂计量合价(元)">
<template slot-scope="{row}">
<span>{{row.temporaryAmount}}</span>
</template>
</el-table-column>
<el-table-column align="center" :prop="activeName=='first'?'remarks':''" label="备注">
<template slot="header">
<span>备注</span>
<el-tooltip v-if="activeName=='first'" class="item" effect="dark" content="说明:修改暂计量单价,须填写价格修订原因。" placement="top-start">
<i class="el-icon-question"></i>
</el-tooltip>
</template>
<template slot-scope="{row,$index}">
<span v-if="activeName!='first'">{{row.remarks}}</span>
<div v-else>
<span v-if="handleType=='view'||!row.editable">{{row.remarks}}</span>
<el-form-item v-else :prop="'taskData.' + $index + '.remarks'" :rules="rulesForRow(row,$index)">
<el-input :maxlength="50" v-model="row.remarks" placeholder="请输入"></el-input>
</el-form-item>
</div>
</template>
</el-table-column>
</el-table>
</el-form>
2 、定义的data部分
//1.data定义校验规则
rulesTask: {
remarks: { required: true, message: '请输入备注', trigger: 'blur' },
temporaryPrice: { required: true, message: '请输入暂计量单价', trigger: 'blur' }
},
//2、计算属性中定义校验的表格数据
computed: {
taskForm() {
return { taskData: this.detailTableData };
},
},
// 3、计算属性中返回单个单元格的校验规则
temporaryPriceRules() {
return (rowData, index) => {
return this.rulesTask.temporaryPrice;
};
},
3、保存的时候和正常的form表单校验一样,toast顶部提示,单元格会标红
this.$refs.taskRef.validate(async valid => {
if (valid) {
this.$message({
type: 'success',
message: '保存成功'
});
} else {
this.$message.error('有必填项未填写');
}
});
4、效果
2、分页表格批量表单校验
1、html部分
<el-form style="margin-top:0" ref="taskRef" :rules="rulesTask" :model="taskForm">
<el-table :key="activeName" :data="displayedData" border :header-cell-style="{ background: '#fff' }">
<el-table-column align="center" type="index" width="80" label="序号"></el-table-column>
<el-table-column align="center" prop="itemNum" label="子目号"></el-table-column>
<el-table-column align="center" prop="itemName" label="子目名称"></el-table-column>
<el-table-column align="center" prop="units" label="单位"></el-table-column>
<el-table-column align="center" prop="quantity" label="数量"></el-table-column>
<el-table-column v-if="activeName !== 'first'" align="center" prop="quantityAfterChange" label="变更后的数量合计"></el-table-column>
<el-table-column align="center" prop="price" label="单价(元)"></el-table-column>
<el-table-column align="center" prop="amount" label="合价(元)"></el-table-column>
<el-table-column v-if="activeName=='first'" align="center" prop="temporaryPrice" label="暂计量单价(元)">
<template slot-scope="{row,$index}">
<span v-if="handleType=='view'||!row.editable">{{row.temporaryPrice}}</span>
<el-form-item v-else :prop="'taskData.' + $index + '.temporaryPrice'" :rules="temporaryPriceRules(row,$index)">
<el-input-number
clearable
style="width:120px"
v-model="row.temporaryPrice"
:max="999999.99"
:min="0"
:precision="2"
:controls="false"
size="mini"
placeholder="请输入"
@change="priceChange(row,$index)"
></el-input-number>
</el-form-item>
</template>
</el-table-column>
<el-table-column v-if="activeName=='first'" align="center" prop="temporaryAmount" label="暂计量合价(元)">
<template slot-scope="{row}">
<span>{{row.temporaryAmount}}</span>
</template>
</el-table-column>
<el-table-column align="center" :prop="activeName=='first'?'remarks':''" label="备注">
<template slot="header">
<span>备注</span>
<el-tooltip v-if="activeName=='first'" class="item" effect="dark" content="说明:修改暂计量单价,须填写价格修订原因。" placement="top-start">
<i class="el-icon-question"></i>
</el-tooltip>
</template>
<template slot-scope="{row,$index}">
<span v-if="activeName!='first'">{{row.remarks}}</span>
<div v-else>
<span v-if="handleType=='view'||!row.editable">{{row.remarks}}</span>
<el-form-item v-else :prop="'taskData.' + $index + '.remarks'" :rules="rulesForRow(row,$index)">
<el-input :maxlength="50" v-model="row.remarks" placeholder="请输入"></el-input>
</el-form-item>
</div>
</template>
</el-table-column>
</el-table>
<pagination :total="detailTableData.length" :page.sync="pageNum" :limit.sync="perPage" @pagination="check"></pagination>
</el-form>
2、计算属性部分
computed: {
displayedData() {
// 根据当前页码和每页显示条目数计算起始和结束索引
const startIndex = (this.pageNum - 1) * this.perPage;
const endIndex = startIndex + this.perPage;
return this.detailTableData.slice(startIndex, endIndex);
},
taskForm() {
return { taskData: this.displayedData };
},
},
3、js逻辑部分
check(){
this.saveProportionForm();
},
// 保存修改
async saveProportionForm() {
this.$refs.proportionForm.validate(async valid => {
if (valid) {
if (this.validateDetailTableData()) {
this.validTable(true);
} else {
this.validTable(false);
this.$message.error('有必填项未填写');
}
} else {
this.$message.error('有必填项未填写');
}
});
},
validTable(type) {
this.$refs.taskRef.validate(async valid => {
if (valid) {
if (type) {
//当校验通过的时候才在这里写ajax之类的请求
}
}
});
},
validateDetailTableData() {
let isValid = true;
for (let i = 0; i < this.detailTableData.length; i++) {
const rowData = this.detailTableData[i];
// 对每一行数据进行校验,根据具体的校验规则进行判断
if (!rowData.temporaryPrice && rowData.editable) {
isValid = false;
}
// 继续校验其他字段...
}
return isValid; // 返回校验结果
},
实现效果