Ant Design FormModel 表单校验 - zptime/blog GitHub Wiki
表单和表单检验是很常用的功能,对于一些常用的校验进行了汇总,如默认校验、自定义校验、列表项校验等。特别是列表项的校验,需要特殊关注下:prop="
cardList.${index}.idType"
, :rules="rules.idType"
官网 FormModel
表单:https://antdv.com/components/form-model-cn/
如下所示,是一个基础的表单信息,其中通过 model
传递表单对象,通过 rules
提供给表单验证规则,并将 FormItem
的 prop
属性设置为需校验的字段名即可。
<template>
<a-form-model
class="m-form"
ref="ruleForm"
:model="form"
:rules="rules"
:label-col="{ span: 4 }"
:wrapper-col="{ span: 14 }"
>
<a-form-model-item label="姓名" prop="name">
<a-input v-model="form.name" />
</a-form-model-item>
<a-form-model-item label="性别" prop="sex">
<a-radio-group v-model="form.sex">
<a-radio value="1">男</a-radio>
<a-radio value="2">女</a-radio>
</a-radio-group>
</a-form-model-item>
<a-form-model-item label="手机号" prop="mobile">
<a-input v-model="form.mobile" ref="mobile" placeholder="请输入手机号" />
</a-form-model-item>
<a-form-model-item label="证件" prop="cardList">
<div v-for="card in form.cardList" :key="card.id" class="card-list">
<a-select v-model="card.idType" placeholder="请选择证件类型">
<a-select-option :value="1">身份证</a-select-option>
<a-select-option :value="2">护照</a-select-option>
</a-select>
<a-input v-model="card.idNo" placeholder="员工证件号码" />
</div>
</a-form-model-item>
<a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">提交</a-button>
</a-form-model-item>
</a-form-model>
</template>
<script>
import * as R from "ramda";
export default {
data() {
return {
form: {
name: "",
sex: "",
mobile: "",
cardList: [
{ id: 1, idType: 1, idName: "身份证", idNo: "111111" },
{ id: 2, idType: 2, idName: "护照", idNo: "sd1234" },
{ id: 3, idType: undefined, idName: "", idNo: "" },
{ id: 4, idType: undefined, idName: "", idNo: "" },
],
},
rules: {},
};
},
methods: {
onSubmit() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
alert("校验成功");
} else {
alert("校验失败");
return false;
}
});
},
},
};
</script>
<style lang="scss">
.m-form {
.ant-form-item-label {
line-height: 32px;
}
.card-list {
display: flex;
align-items: center;
margin-bottom: 24px;
.ant-select {
width: 218px;
margin-right: 16px;
}
}
}
</style>
Form
组件提供了基础的表单验证功能,对应大部分情况都是可以处理的。具体的配置项可查看官网,如下只列举了一些基本的配置required
,message
,trigger
。
<script>
export default {
data() {
return {
rules: {
name: [
{
required: true, // 是否必选
message: "请输入用户姓名", // 校验文案
trigger: ["change", "blur"], // 触发时机,可以为数组,也可为字符串
},
{
min: 3, // 最小长度
max: 5, // 最大长度
message: "姓名长度应该在3~5之间,才符合要求",
trigger: "blur",
},
],
sex: [
{
required: true,
message: "请选择性别",
trigger: "change",
},
],
},
};
},
};
</script>
对于一些特殊的情况,也可以通过自定义函数validator
来校验。如下,以手机号和证件信息为例进行校验,其中手机号validateMobile
不仅校验了必填,还校验了格式,而且报错后还可以定位到具体位置focus()
,方便修改。
<script>
export default {
data() {
// 手机号验证
let validateMobile = (rule, value, callback) => {
if (R.isNil(value) || R.isEmpty(value)) {
// 定位到错误数据框
this.$refs.mobile.focus();
return callback(new Error("请输入手机号"));
}
// 格式校验
let reg = /^1[0-9]\d{9}$/;
if (!reg.test(value)) {
this.$refs.mobile.focus();
return callback(new Error("请输入格式正确的手机号"));
}
};
// 证件校验
let validateCard = (rule, list, callback) => {
let flag = false;
if (!(list && list.length)) {
flag = true;
} else {
R.forEach((o) => {
if (!o.idType || !o.idNo) flag = true;
}, list);
}
if (flag) {
callback(new Error("请填写证件信息"));
}
};
return {
rules: {
mobile: [
{ required: true, validator: validateMobile, trigger: "change" },
],
cardList: [
{ required: true, validator: validateCard, trigger: "change" },
],
},
};
},
};
</script>
整体检验效果如下图所示,错误信息会展示在对应的表单下方:
上面对于证件信息的校验是整体校验
,只要有一个不满足条件,整个列表项都会标红,这样体验感就比较差了。正常还是倾向于哪个没填标注哪个,所以还是要对列表的每一项进行单独校验
。
最关键的配置就是:prop="
cardList.${index}.idType"
,可以配置成.
连接的字符串形式,专门处理数组或对象形式的数据。而且要和校验规则:rules="rules.idType"
对应起来,不然不会起作用的。
<template>
<div
v-for="(card, index) in form.cardList"
:key="card.id"
class="card-list card-list2"
>
<a-form-model-item
:label="`证件${index + 1}`"
:prop="`cardList.${index}.idType`"
:rules="rules.idType"
>
<a-select v-model="card.idType" placeholder="请选择证件类型">
<a-select-option :value="1">身份证</a-select-option>
<a-select-option :value="2">护照</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
:prop="`cardList.${index}.idNo`"
:rules="rules.idNo"
>
<a-input v-model="card.idNo" placeholder="员工证件号码" />
</a-form-model-item>
</div>
</template>
<script>
export default {
data() {
return {
rules: {
idType: [
{
required: true,
message: "请选择证件类型",
trigger: "change",
},
],
idNo: [
{
required: true,
message: "请填写证件号码",
trigger: "change",
},
],
},
};
}
}