在做项目的时候难免会遇到各种复杂的表单校验,之前也遇到过这种类似的问题,这次就来总结一下,便于以后可以提高工作效率,看标题可能不太理解具体是什么功能,下面用图来解释一下:
如上图所示:可以动态添加/删除form表单以及table行,并且需要比较table每行“销售价格”和“市场价格”的大小进行表单校验。
实现方式有两种:
第一种方式:
实现思路:将<el-form>
标签放在最外层,只使用一个formRef,每个<el-form-item>
中的props都使用formList.0.table.0.orderSn
这种方式,例如:
<el-form ref="formRef" :model="formData" label-width="100px" :inline="true">
<el-container v-for="(item, index) in formData.formList" :key="index">
...
<el-form-item :prop="`formList.${index}.table.${$index}.orderSn`" :rules="tableRules.orderSn">
</el-container>
</el-form>
主要难点是如何比较table行内元素的大小(例:销售价、市场价),这里可以根据rule
可以获取到formList
和table
两个数组的键值index
写法如下:
const salePriceValidate = (rule, value, callback) => {
const indexs = rule.field.match(/\d+/g)
const marketPrice = formData.value.formList[indexs[0]].table[indexs[1]].marketPrice
if (value && marketPrice && value > marketPrice) {
callback(new Error('不能大于市场价格'));
} else {
callback();
}
}
salePrice: [
{ required: true, message: '请输入销售价格', trigger: 'blur' },
{ validator: salePriceValidate, trigger: 'blur' }
],
完整代码:
第二种方式:
实现思路:在<el-form>
外层进行v-for
,根据formList数组定义多个formRef,form提交时需要for循环校验每个form,写法如下:
<el-container v-for="(item, index) in formList" :key="index">
<el-form :ref="(el) => formRefs[index] = el" :rules="formRules"></el-form>
</el-container>
const submit = async () => {
try {
const promises = formRefs.value.map(item => item && item.validate())
const results = Promise.all(promises)
if ((await results).every(res => res)) {
console.log(formList.value, '---formList')
}
} catch (error) {
console.log(error, '---err')
}
}
主要难点:还是如何比较table行内元素的大小(例:销售价、市场价),这里就不能用rule.field
来获取键值了,可以通过:rules="tableRules(row)"
传参处理,写法如下:
<el-form-item :prop="`table.${$index}.marketPrice`" :rules="tableRules(item.table[$index]).marketPrice"></el-form-item>
const salePriceValidate = (row) => {
return (rule, value, callback) => {
if (value && row.marketPrice && value > row.marketPrice) {
callback(new Error('不能大于市场价格'));
} else {
callback();
}
}
}
const tableRules = (row) => {
return {
salePrice: [
{ required: true, message: '请输入销售价格', trigger: 'blur' },
{ validator: salePriceValidate(row), trigger: 'blur' }
],
}
}
完整代码: