[element-ui]el-form+el-table实现多个表格内容编辑和校验
·
背景:
每个模块的数据是调取后端接口获取的,有数据则展示对应模块。每个模块内的表格都可以修改出价,不同类型的数据出价范围也不一样,需要进行校验。在保存设置的时候,校验成功才提交,否则阻断。
思路:
第一次是给每个模块内的表格的el-input绑定blur事件,如果输入值的范围不对,则弹出message消息提示,最后在保存设置的时候遍历所有数据,如果值不对则提示且阻断。这种方法会导致当在修改完某个值直接点提交则会触发两次提示,体验不好。
第二次改为表单校验,提示更加友好美观,体验也更流畅,符合产品要求。
以下展示第二种效果以及分享写法。
最终效果:
写法:
1、html部分:这里的html结构是一个el-form里面嵌套el-table,el-table再嵌套表单项el-form-item。
注意:
- 需要给每个表单绑定不同的ref,保存将根据ref对应的表单进行校验
- 因为嵌套关系,el-table的数据绑定的是:data="formData.costControlList"
- 表格中的表单项校验需要绑定prop字段,这个字段根据表格索引动态绑定,将要校验的字段在表格数据中对应。写法为
:prop="`costControlList.${scope.$index}.priceNext`"
- 校验规则可以在el-form上一次性传递,也可以在单个的表单域上传递属性的验证规则。因为我有多个表单,每个表单只有一项需要校验,所以我采用后一种方式。写法为
:rules="[{ required: true, message: '请输入'}, { required: true, validator: (rule, value, callback,type) => costValidator(rule, value, callback,scope.row.constraintType)}]">
解释:动态绑定一个数组,第一条为必填校验,第二条为自定义校验规则,因为我这个校验还需要根据不同的类型来判断范围,所以我需要多传递一个类型参数。如果不需要这样判断,直接调用校验方法即可。
完整html代码如下:
<el-form ref="costForm" :model="formData">
<el-table :data="formData.costControlList" ref="costTable" max-height="400">
<el-table-column label="xx" prop="xx"></el-table-column>
<el-table-column label="xx" prop="xx"></el-table-column>
<el-table-column prop="xx" label="xx"></el-table-column>
<el-table-column prop="priceNext" label="修改xx">
<template v-slot="scope">
<el-form-item :prop="`costControlList.${scope.$index}.priceNext`"
:rules="[{required: true, message: '请输入'},
{required:true, validator:
(rule, value, callback,type) => costValidator(rule, value, callback,scope.row.constraintType)}]">
<el-input v-model.trim="scope.row.priceNext"
@keyup.native="handleNumberType"
style="width: 250px"
placeholder="请输入"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
2、自定义校验规则
costValidator(rule, value, callback,type) {
if(type==='conv') {
if(value < 3 || value > 9999.99) {
callback('请输入3-9999.99的数字')
}
}else if(type==='click') {
if(value < 0.05 || value > 99.99) {
callback('请输入0.05-99.99的数字')
}
}
callback()
},
3、提交行为
- 利用promise封装一个验证表单的函数,如果表单不存在或者校验通过,则resolve,否则reject,将返回的结果添加到一个数组。
- 点击保存时,循环校验每个表单,利用promise的all方法,如果校验全部通过则处理数据调取接口,不通过则会报错。
代码如下:
checkForm(formName){ //封装验证表单的函数
var result = new Promise((resolve,reject) => {
if(!this.$refs[formName]) {
resolve();
}else {
this.$refs[formName].validate((valid) => {
if(valid) {
resolve();
} else {
reject()
}
})
}
})
this.resultArr.push(result) //把promise得到的结果push进数组保存
},
handleSave() {
this.resultArr = []
let formArr = ['costForm','roiForm','crowdForm']
let tempArray = []
formArr.forEach(item => { // 根据表单的ref校验
this.checkForm(item)
})
Promise.all(this.resultArr).then(response => {
let totalArray = this.formData.costControlList.concat(this.formData.roiControlList).concat(this.formData.customBidList)
tempArray = totalArray.map(item => {
if(item.crowdList.length) {
item.crowdListTemp = item.crowdList.map(p=>{
return {
crowdId: p.crowdId,
bidPrice: p.priceNext,
}
})
}
return {
campaignId: item.campaignId,
bidType: item.bidType,
constraintType: item.constraintType,
constraintValue: item.priceNext, //修改后的出价
crowdList: item.crowdListTemp || []
}
})
this.loading = true;
this.$axios.post('xxxx', {
bizCode: this.bizCode,
bidPriceList: tempArray
}).then(response => {
this.loading = false;
if(response.data.status === 0) {
this.$message.success('修改成功');
this.$emit("close",true)
}
})
}).catch(
console.log("error")
)
},
更多推荐
已为社区贡献8条内容
所有评论(0)