Vue.js — ant-design数组表单验证

一、前言

常见的表单验证是对 对象中 单个字段的验证,那如何对数组中的每一项做到验证呢?例如,我们有这样一个需求:公司系统需要录入员工信息,可以同时添加多个员工并且对这些信息进行格式校验,实现如下效果:
Vue.js — ant-design数组表单验证_第1张图片

二、实现

首先需要准备好 form 数据和 rules 验证规则

form: {
    member: [
        { name: "", sex: "", age: "" }
    ],
},
rules: {
    name: { required: true, message: "请输入姓名" },
    sex: { required: true, message: "请选择性别" },
    age: { required: true, message: "请选择年龄" },
},

然后在 form 中去循环 member 数组,将三个 formItem 当成一组,循环生成多组数据,这样就实现了数组表单。接下来就是实现表单验证:
表单验证必须要给 form-item 设置 name 属性,name 接受两种形式

  1. name = "age",校验 form 中的 age 字段
  2. :name="['member', index, 'age']",校验 form 中的 member 数组,对数组中的第 index 项的 age 字段进行格式验证,可以理解为校验 member[index].age 字段
<a-form ref="formRef" :model="form">
   <div class="member" v-for="(item, index) in form.member" :key="item">
        <a-form-item
            label="姓名"
            :name="['member', index, 'name']"
            :rules="rules.name"
        >
            <a-input v-model:value="item.name" />
        </a-form-item>
        <a-form-item
            label="性别"
            :name="['member', index, 'sex']"
            :rules="rules.sex"
        >
            <a-select v-model:value="item.sex">
                <a-select-option value="1"></a-select-option>
                <a-select-option value="0"></a-select-option>
            </a-select>
        </a-form-item>
        <a-form-item
            label="年龄"
            :name="['member', index, 'age']"
            :rules="rules.age"
        >
            <a-input v-model:value="item.age" />
        </a-form-item>
    </div>
</a-form>

最后就是一些细节的实现:增加 item 项、删除 item 项、提交表单、重置表单。
以下附上 form-valid.vue 的全部代码

<template>
    <h2 style="margin-bottom: 20px">Form 数组表单验证</h2>
    <a-form ref="formRef" :model="form">
        <div class="member" v-for="(item, index) in form.member" :key="item">
            <a-form-item
                label="姓名"
                :name="['member', index, 'name']"
                :rules="rules.name"
            >
                <a-input v-model:value="item.name" />
            </a-form-item>
            <a-form-item
                label="性别"
                :name="['member', index, 'sex']"
                :rules="rules.sex"
            >
                <a-select v-model:value="item.sex">
                    <a-select-option value="1"></a-select-option>
                    <a-select-option value="0"></a-select-option>
                </a-select>
            </a-form-item>
            <a-form-item
                label="年龄"
                :name="['member', index, 'age']"
                :rules="rules.age"
            >
                <a-input v-model:value="item.age" />
            </a-form-item>
            <a-form-item>
                <a-button @click="delItem(index)">
                    <MinusOutlined />
                </a-button>
            </a-form-item>
        </div>
    </a-form>
    <a-button class="add-btn" @click="addItem"><PlusOutlined /></a-button>
    <a-button type="primary" html-type="submit" @click="submitForm">Submit</a-button>
    <a-button @click="resetForm">Reset</a-button>
</template>

<script>
import { Form, Input, Select, Button } from "ant-design-vue";
import { MinusOutlined, PlusOutlined } from "@ant-design/icons-vue";

export default {
    components: {
        [Form.name]: Form,
        [Form.Item.name]: Form.Item,
        [Input.name]: Input,
        [Select.name]: Select,
        [Select.Option.displayName]: Select.Option,
        [Button.name]: Button,
        MinusOutlined,
        PlusOutlined,
    },
    data() {
        return {
            form: {
                member: [
                    { name: "", sex: "", age: "" }
                ],
            },
            rules: {
                name: { required: true, message: "请输入姓名" },
                sex: { required: true, message: "请选择性别" },
                age: { required: true, message: "请选择年龄" },
            },
        };
    },
    methods: {
        submitForm() {
            this.$refs.formRef.validate().then(() => {
                    console.log(123);
            }, (err) => {
                    console.log(err);
            });
        },
        resetForm() {
            this.$refs.formRef.resetFields();
        },
        addItem() {
            const item = { name: "", sex: "", age: "" };
            this.form.member.push(item);
        },
        delItem(i) {
            if (this.form.member.length === 1) {
                return;
            }
            this.form.member.splice(i, 1);
        },
    },
};
</script>

<style lang='less' scoped>
.member {
    display: flex;

    .ant-form-item {
        margin-right: 10px;
        width: 200px;
    }
}

.ant-btn {
    margin-right: 10px;
}
</style>```

你可能感兴趣的:(vue.js,ant-design,vue.js)