当时在使用element-ui开发后台项目的时候,遇到表单中数组字段需要验证,试了好几种写法都没能弄出来,甚至当时都没想到该怎么描述去百度搜索别人的经验借鉴一下,现在我将这个现象记录下来,方便自己,也希望能帮助还没遇到或者即将遇到此问题的你。
当时的需求:
选择允许加床数量,会自动创建选中数量的加床模板,加床模板字段包含加床类型、是否免费。加床模板其实就是一个对象数组,每个对象中的字段(加床类型、是否免费)同时也需要验证。
先贴个效果截图
下面贴上部分源码,后面再解释一下:
form4.vue中需要验证的部分代码
<el-form
:model="form"
label-position="top"
v-show="stepIndex==0"
ref="formRef"
>
<template v-if="form.allowExtraBed == 1">
<el-form-item
label="允许加床数量"
prop="extraBedNum"
label-width="280px"
verify
>
<el-select
v-model="form.extraBedNum"
placeholder="请选择"
@change="onExtraBedNumChange"
clearable
>
<el-option
v-for="its in [1, 2, 3, 4, 5]"
:key="its"
:label="its"
:value="its"
>
</el-option>
</el-select>
</el-form-item>
<div v-for="(item, index) in form.extraBedData" :key="index">
<div class="area-wrapper">
<h3>加床{{ index + 1 }}</h3>
<el-form-item
label="加床类型"
:prop="`extraBedData.${index}.extraBedType`"
verify
>
<el-select
v-model="item.extraBedType"
placeholder="请选择"
style="width: 100%"
clearable
>
<el-option
v-for="item in dict.extra_bed_type"
:key="item.dataValue"
:label="item.dataName"
:value="item.dataValue"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="是否免费"
:prop="`extraBedData.${index}.free`"
verify
>
<el-select
v-model="item.free"
placeholder="请选择"
style="width: 100%"
clearable
>
<el-option
v-for="item in [
{ dataName: '是', dataValue: 1 },
{ dataName: '否', dataValue: 0 },
]"
:key="item.dataValue"
:label="item.dataName"
:value="item.dataValue"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
v-if="item.free == 0"
label="加床价格"
:prop="`extraBedData.${index}.extraBedFee`"
:verify="{ type: 'pint', lte: 999 }"
>
<el-input placeholder="请输入内容" v-model="item.extraBedFee">
<template slot="append">/元</template>
</el-input>
</el-form-item>
</div>
</div>
</template>
</el-form>
**大家注意,其实多层循环验证关键就是在 el-form-item 上 的
:prop="`extraBedData.${index}.extraBedType`" // 推荐写法
// :prop="'extraBedData'+index+'.extraBedType'" // 不推荐写法
extraBedData就是数组名,index是数组循环索引值,extraBedType为需要验证的字段。
总结起来就是:
:prop="`数组字段.${数组循环索引值}.数组对象中待验证字段`"
// :prop="'数组字段.' + 数组循环索引值 + '数组对象中待验证字段'"
遇到问题不要慌,多想想,查查资料,或者请教下同事朋友,困难并不可怕。
哦,对了,大家是否看到了我代码中的verify,这是我们公司的几位小伙伴基于element-ui开发的一款表单验证插件,很实用,在npm中搜索 element-verify 可查看其文档。有兴趣的可以下载使用,当然你直接使用element-ui提供的rules来验证也是没有任何问题的,譬如上面的
<el-form-item
label="是否免费"
:prop="`extraBedData.${index}.free`"
verify
>
</el-form-item>
就可以这样写
<el-form-item
label="是否免费"
:prop="`extraBedData.${index}.free`"
:rules="{
required: true,
message: '必填项',
}"
>
</el-form-item>
一般饿了么表单都是提交表单时,通过 validate 对整个表单进行校验的,
this.$refs.formRef.validate(valid => {
if (valid) {
}
})
如果要对部分表单字段进行校验,我们使用validateField即可。比如我要对form.name中的name字段单独进行验证,
this.$refs.formRef.validateField("name")
如果我要单独验证的是一个数组对象中的某个字段呢,又该如何实现呢?
let lists = this.formData.targetList;
targetList.forEach((item, index) => {
this.$refs.formDialogRef.validateField(
`targetList.${index}.targetChildField`
);
});
想了解更多,可阅读我另一篇文章 ,点此进入。
好了,关于多层循环验证的问题就啰嗦到这里啦。
下面记录下这个页面完整的js,当然,跟我们讨论的问题无关啦,大家可以略过。
import { mapGetters } from "vuex";
export default {
props: {
form: {
type: Object,
required: true,
default() {
return {};
},
},
status: {
type: String,
required: true,
},
},
computed: {
...mapGetters(["dict"]),
},
data() {
return {};
},
watch: {
// 是否允许加床选择否,清空加床信息、加床数量
"form.allowExtraBed": {
handler(nv, ov) {
if (nv == 0) {
this.$set(this.form, "extraBedData", []);
this.$set(this.form, "extraBedNum", null);
}
if (nv == 1) {
if (
!this.form.extraBedData ||
(this.form.extraBedData.constructor === Array &&
this.form.extraBedData.length == 0)
) {
this.$set(this.form, "extraBedNum", 1);
this.onExtraBedNumChange(1);
}
}
},
immediate: true,
deep: true,
},
},
methods: {
onExtraBedNumChange(nv) {
let temp = [];
for (let i = 0; i < nv; i++) {
temp.push({
extraBedType: null,
free: null,
extraBedFee: null,
});
}
this.$set(this.form, "extraBedData", temp);
},
},
};