提要
这篇文章算是《深入了解 Element Form 表单动态验证问题》的延伸。
相信大伙肯定遇到过这样的需求,在一个表单内容里面嵌套一个表格,同时需要校验表格里面的某些单元格内容,如果自己实现这样的校验,一般就只能遍历表格内容进行判断,然后修改标识符给出提示。
若使用的是 elementUI 组件库,那么这件事其实就变得非常简单了,只需要在表格单元格放入 ElFormItem 组件下,即可实现指定单元格的校验。
单元格静态校验
<template>
<el-form :model="form" label-position="left" label-width="100">
<el-form-item label="其他表单项" prop="name" :rules="rules.name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="表格Table">
<el-table :data="form.tableData" border stripe>
<el-table-column label="该列单元格校验">
<template slot-scope="{ row, $index }">
<el-form-item
:prop="`tableData.${$index}.input`"
:rules="rules.input"
>
<el-input v-model="row.input"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</template>
<script>
export default {
name: "Demo",
data() {
return {
form: {
name: "",
tableData: [
{ input: "" },
{ input: "" },
{ input: "" },
{ input: "" },
{ input: "" }
]
},
rules: {
name: [
{ required: true, trigger: ["blur", "change"], message: "请选择" }
],
input: [
{ required: true, trigger: ["blur", "change"], message: "请选择" }
]
}
};
}
};
</script>
其效果如下:
单元格动态校验
根据上面的方法,结合《深入了解 Element Form 表单动态验证问题》,即可实现单元格动态校验。
<template>
<div>
<el-form ref="form" :model="form" label-position="left" label-width="100">
<el-form-item label="其他表单项" prop="name" :rules="rules.name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="表格Table">
<el-table :data="form.tableData" border stripe>
<el-table-column label="是否校验">
<template slot-scope="{ row, $index }">
<el-form-item
:prop="`tableData.${$index}.radio`"
:rules="rules.radio"
>
<el-radio-group v-model="row.radio">
<el-radio label="Y">是</el-radio>
<el-radio label="N">否</el-radio>
</el-radio-group>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="动态校验">
<template slot-scope="{ row, $index }">
<el-form-item
:prop="`tableData.${$index}.remark`"
:rules="row.radio === 'N' ? [] : rules.remark"
:required="false"
>
<el-input v-model="row.remark"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<el-button type="primary" @click="submit">提交</el-button>
</div>
</template>
<script>
export default {
name: "Demo",
data() {
return {
form: {
name: "",
tableData: [
{ radio: "", remark: "" },
{ radio: "", remark: "" },
{ radio: "", remark: "" },
{ radio: "", remark: "" },
{ radio: "", remark: "" }
]
},
rules: {
name: [
{ required: true, trigger: ["blur", "change"], message: "请输入" }
],
radio: [
{ required: true, trigger: ["blur", "change"], message: "请输入" }
],
remark: [
{ required: true, trigger: ["blur", "change"], message: "请输入" }
]
}
};
},
methods: {
submit() {
this.$refs.form.validate(bool => {
if (bool) {
console.log("submit");
}
});
}
}
};
</script>
其效果如下:
原理
查看 elementUI 中 form
组件的源码,可以发现 el-form
组件在 created
钩子函数中注册el.form.addField
事件的监听,当触发该事件时会将 el-form-item
实例加入到 fields
中。
// form.vue
created() {
this.$on('el.form.addField', (field) => {
if (field) {
this.fields.push(field);
}
});
//...
}
当 el-form-item
挂载 mounted
后,触发 el-form
的 el.form.addField
事件
// form-item.vue
mounted() {
if (this.prop) {
this.dispatch('ElForm', 'el.form.addField', [this]);
//...
}
}
所以只要 el-form-item
组件在 el-form
组件的插槽内,就可以加入到校验队列中。