vue3 +elementplus | vue2+elementui dynamically add or delete a single form field through validation rules

renderings

Click +’ to add a new line, click -’ to delete a line

vue3 + elementplus writing method

template

<el-dialog v-model="dialogFormVisible" :title="title">
            <el-form ref="ruleFormRef" :model="form" :inline="true" label-width="120px" class="demo-ruleForm"
                :size="formSize" status-icon>
                <el-form-item label="Teacher number:" prop="code" :rules="[{<!-- --> required: true, message: 'Please enter the teacher number' , trigger: 'blur' },
                {<!-- --> min: 4, message: 'The length cannot be less than four digits', trigger: 'blur' }]">
                    <el-input v-model="form.code" />
                </el-form-item>
                <el-form-item label="Teacher's name:" prop="name" :rules="[{ required: true, message: 'Please enter the teacher's name', trigger: 'blur\ ' }]">
                    <el-input v-model="form.name" />
                </el-form-item>
                <div v-for="(item, index) in form.addList" :key="item.key" flex>
                    <!--Note: The official example uses form's addList as the prop mark -->
                    <el-form-item label="Teaching Department:" :prop="'addList.' + index + '.yuanxi'" :rules="{<!-- -- >
                        required: true,
                        message: 'Teaching department cannot be empty',
                        trigger: 'change',
                    }">
                        <el-select v-model="item.yuanxi" placeholder="Please choose" @change="chooseClass(index)">
                            <el-option :label="yx.department" :value="yx.id" v-for="(yx, indexyx) in departmentList"
                                :key="indexyx"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="Teaching class:" :prop="'addList.' + index + '.banji'" :rules="{<!-- -->
                        required: true,
                        message: 'The teaching class cannot be empty',
                        trigger: 'change',
                    }">
                        <el-select v-model="item.banji" placeholder="Please select">
                            <el-option :label="bj.class_title" :value="bj.id" v-for="(bj, indexbj) in item.classesList"
                                :key="indexbj"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-icon :size="26" color="#264E71" @click="removeOne(index)">
                        <Remove />
                    </el-icon>
                    <el-icon :size="26" color="#264E71" @click="plusOne(index)">
                        <CirclePlus />
                    </el-icon>

                </div>

                <el-form-item>
                    <el-button type="primary" @click="submitForm(ruleFormRef)">Submit
                    </el-button>
                    <el-button @click="resetForm(ruleFormRef)">Reset</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>

js

<script setup lang="ts">
import {<!-- --> reactive, ref, onMounted } from 'vue'
import type {<!-- --> FormInstance, FormRules } from 'element-plus'
import {<!-- --> EpPropMergeType } from 'element-plus/es/utils';
import {<!-- --> departmentDepartmentList, departmentClassesList } from '../../request/api'
import {<!-- --> DepartmentListtype } from '~/type/login';
import userMainStore from "../../store/modules/app";
const mainStore = userMainStore();
import {<!-- --> CirclePlus, Remove } from '@element-plus/icons-vue';


const props = defineProps({<!-- -->
    title: {<!-- -->
        default: '',
        type: String,
    },
})

const dialogFormVisible = ref(false)
interface addlistType {<!-- -->
    yuanxi: string,
    banji: string,
    classesList: any,
    key: number

}
interface RuleForm {<!-- -->
    code: string,
    name: string,
    addList: addlistType[]
}
const formSize = ref<EpPropMergeType<StringConstructor, "" | "default" | "small" | "large", unknown> | undefined>('default')
const ruleFormRef = ref<FormInstance>()
const form = reactive<RuleForm>({<!-- -->
    code: '',
    name: '',
    addList: [
        {<!-- -->
            yuanxi: '',
            banji: '',
            classesList: [],
            key: Date.now(),
        }
    ]
})
const plusOne = (index: number) => {<!-- -->
    form.addList.push(
        {<!-- -->
            yuanxi: "",
            banji: '',
            classesList: [],
            key: Date.now(),
        }
    )
    console.log(form, 'form00000');

}
const removeOne = (index: number) => {<!-- -->
    form.addList.splice(index, 1)
}
let departmentList = ref([] as any[])
const chooseClass = (index: number) => {<!-- -->

     form.addList[index].classesList = []
     form.addList[index].banji = ''

    classes(index)

}
const classes = (index: number) => {<!-- -->
    let params = {<!-- -->
        token: mainStore.Authorization,
        limit: 1000,
        department: form.addList[index].yuanxi

    };
    departmentClassesList(params).then((res) => {<!-- -->
        let {<!-- --> data, code } = res;
        if (code == 200) {<!-- -->
            form.addList[index].classesList = data.list
            console.log(form, 'form11111');
        }
    });
}

const submitForm = async (formEl: FormInstance | undefined) => {<!-- -->
    if (!formEl) return
    await formEl.validate((valid, fields) => {<!-- -->
        if (valid) {<!-- -->
            // console.log('submit!')
            console.log(form, 'form')

        } else {<!-- -->
            console.log('error submit!', fields)
        }
    })
}

const resetForm = (formEl: FormInstance | undefined) => {<!-- -->
    if (!formEl) return
    formEl.resetFields()
}
const showDio1 = () => {<!-- -->
    dialogFormVisible.value = true
}
const department = () => {<!-- -->
    let params: DepartmentListtype = {<!-- -->
        token: mainStore.Authorization,
        limit: 1000,
        page: 1

    };
    departmentDepartmentList(params).then((res) => {<!-- -->
        let {<!-- --> data, code } = res;
        if (code == 200) {<!-- -->
            departmentList.value = data.list


        }
    });
}
//Part 2: Exposure method
defineExpose({<!-- -->
    showDio1
})
onMounted(() => {<!-- -->
    department()
})
</script>

vue2 + elementui writing method

template

<el-dialog :title="title" :visible.sync="centerDialogVisible" width="806px" @close="closeDio()"
            v-if="centerDialogVisible">
            <div>
                <el-form ref="form" :inline="true" :model="form" label-width="120px">
                    <el-form-item label="Teacher number:" prop="code" :rules="[
                        {<!-- --> required: true, message: 'Please enter the teacher number', trigger: 'blur' },
                        {<!-- --> min: 4, message: 'The length cannot be less than four digits', trigger: 'blur' }
                    ]">
                        <el-input v-model="form.code" onkeyup="value=value.replace(/[\W]/g,'')"
                            placeholder="Please enter the teacher number"></el-input>
                    </el-form-item>
                    <el-form-item label="Teacher Name:" prop="name" :rules="[
                        {<!-- --> required: true, message: 'Please enter the teacher's name', trigger: 'blur' }
                    ]">
                        <el-input v-model="form.name" type="text" @input="
                            form.name = form.name.replace(
                                /[^\\一-\\龥]/g,
                                ''
                            )
                            " placeholder="Please enter the teacher's name"></el-input>
                    </el-form-item>
                    <div flex v-for="(item, index) in form.addList" :key="index">
                        <el-form-item label="Teaching Department:" :prop="'addList.' + index + '.yuanxi'" :rules="{<!-- -- >
                            required: true, message: 'Teaching department cannot be empty', trigger: 'change'
                        }">
                            <el-select v-model="item.yuanxi" filterable placeholder="Please select" @change="chooseClass(index)">
                                <el-option :label="yx.department" :value="yx.id" v-for="(yx, indexyx) in departmentList"
                                    :key="indexyx"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="Teaching class:" :prop="'addList.' + index + '.banji'" :rules="{<!-- -->
                            required: true, message: 'Teaching class cannot be empty', trigger: 'change'
                        }">
                            <div flex="cross:center">
                                <el-select v-model="item.banji" filterable placeholder="Please select"
                                    @change="changeClass(item.banji, item.yuanxi, index)">
                                    <el-option :label="bj.class_title" :value="bj.id"
                                        v-for="(bj, indexbj) in item.classesList" :key="indexbj"></el-option>
                                </el-select>
                            </div>
                        </el-form-item>
                        <span style="margin-top:5px; ">
                            <i class="el-icon-remove-outline" style="color: #264E71;" @click="removeOne(index)"
                                v-show="form.addList.length > 1"></i>
                            <i class="el-icon-circle-plus-outline" style="color: #264E71;" @click="plusOne(index)"></i>
                        </span>
                    </div>


                </el-form>
            </div>
            <span slot="footer" class="dialog-footer">
                <el-button class="dioSave btnOk dioBigSave" type="primary" @click="AddOrder('form')">Submit</el-button>
                <el-button class="dioSave btnCancel dioBigSave" @click="resetForm1" v-if="flag == 0">Reset</el-button>
                <el-button class="dioSave btnCancel dioBigSave" @click="resetForm1" v-if="flag == 1">Reset</el-button>
            </span>
        </el-dialog>

js

<script>
import {<!-- -->
    addTeacher,
    updateTeacher,
    departmentDepartmentList,
    departmentClassesList
} from '@/api/api';
export default {<!-- -->
    components: {<!-- -->},
    data() {<!-- -->
        return {<!-- -->
            form: {<!-- -->
                addList: [
                    {<!-- -->
                        yuanxi: "",

                        banji: '',
                        classesList: []

                    }
                ],
            },

            departmentList: [],


            centerDialogVisible: false,

        };
    },
    props: {<!-- -->
        title: {<!-- -->
            type: String
        },
        flag: {<!-- -->
            type: Number
        }
    },
    computed: {<!-- -->},
    watch: {<!-- -->

    },
    methods: {<!-- -->
        changeClass(banji, yuanxi, index) {<!-- -->
            console.log(banji, '---banji');
            console.log(yuanxi, 'yuanxi');

        },
        AddOrder(form) {<!-- -->


            this.$refs[form].validate((valid) => {<!-- -->
                if (valid) {<!-- -->
                    if (this.flag == 1) {<!-- -->
                        this.updatesubmit()
                    } else {<!-- -->
                        this.submit()
                    }

                } else {<!-- -->
                    console.log('error submit!!');
                    return false;
                }
            });

        },
        xunhuan() {<!-- -->

        },
        submit() {<!-- -->
            let department = []
            let classes = []

            this.form.addList = Array.from(new Set(this.form.addList.map(JSON.stringify))).map(JSON.parse);

            console.log(this.form.addList, 'addList');

            this.form.addList.forEach((item) => {<!-- -->
                department.push(item.yuanxi)
                classes.push(item.banji)
            })



            let params = {<!-- -->
                token: this.$store.state.Authorization,
                code: this.form.code,
                name: this.form.name,
                department: String(department),
                classes: String(classes),
                account: JSON.parse(localStorage.getItem('loginInfo')).account

            };

            addTeacher(params).then((res) => {<!-- -->
                let {<!-- --> data, code } = res;
                if (code == 200) {<!-- -->
                    this.$message.success('Add successfully!')
                    this.form.code = ''
                    this.form.name = ''
                    this.form.addList = [
                        {<!-- -->
                            yuanxi: "",

                            banji: '',
                            classesList: []

                        }
                    ]
                    // this.$refs['form'].resetFields();
                    // this.resetForm()
                    this.centerDialogVisible = false
                    this.$emit('addNewSuccess', true)

                }
            });
        },

        updatesubmit() {<!-- -->

            let department = []
            let classes = []
            this.form.addList = Array.from(new Set(this.form.addList.map(JSON.stringify))).map(JSON.parse);
            this.form.addList.forEach((item) => {<!-- -->
                department.push(item.yuanxi)
                classes.push(item.banji)
            })


            let params = {<!-- -->
                token: this.$store.state.Authorization,
                code: this.form.code,
                name: this.form.name,
                department: String(department),
                classes: String(classes),
                account: JSON.parse(localStorage.getItem('loginInfo')).account,
                uid: this.editId

            };


            updateTeacher(params).then((res) => {<!-- -->
                let {<!-- --> data, code } = res;
                if (code == 200) {<!-- -->
                    this.$message.success('Editing successful!')
                    this.form.code = ''
                    this.form.name = ''
                    this.form.addList = [
                        {<!-- -->
                            yuanxi: "",

                            banji: '',
                            classesList: []

                        }
                    ]

                    this.centerDialogVisible = false
                    this.$emit('addNewSuccess', true)

                }
            });
        },
        closeDio() {<!-- -->
            console.log('Execute');
            this.resetForm1()
        },
        resetForm0() {<!-- -->
            this.$refs['form'].resetFields();
            // this.form = {}
            // this.departmentList = []
            this.form.code = ''
            this.form.name = ''
            this.form.addList = [
                {<!-- -->
                    yuanxi: "",

                    banji: '',
                    classesList: []

                }
            ]

        },
        resetForm1() {<!-- -->
            this.form = {<!-- -->
                addList: [
                    {<!-- -->
                        yuanxi: "",

                        banji: '',
                        classesList: []

                    }
                ]
            }

        },
        showDio1() {<!-- -->
            this.centerDialogVisible = true

            this.department()
        },
        showDio(row) {<!-- -->
            this.centerDialogVisible = true

            // if (row) {<!-- -->
            console.log(row.id, 'row')
            this.editId = row.id
            // this.form.code = row.code
            // this.form.name = row.name
            if (row.clas) {<!-- -->
                let arrClasses = (row.classes).split(',')
                console.log(row.clas, 'clas');
                let arrdepartment = []
                row.clas.forEach((ele, i) => {<!-- -->
                    arrdepartment.push(ele.department_id)
                })
                let addList = []
                for (let i = 0; i < arrClasses.length; i + + ) {<!-- -->

                    addList.push(
                        {<!-- -->
                            yuanxi: '',
                            banji: Number(arrClasses[i]),
                            classesList: []

                        }
                    )

                }
                for (let j = 0; j < arrdepartment.length; j + + ) {<!-- -->
                    addList[j].yuanxi = Number(arrdepartment[j])
                }



                this.department()

                // this.form.addList = addList
                this.form = {<!-- -->
                    code: row.code,
                    name: row.name,
                    addList: addList
                }
                console.log(addList);
                arrClasses.forEach((item, index) => {<!-- -->
                    this.classes(index)
                })
            } else {<!-- -->
                this.form = {<!-- -->
                    code: row.code,
                    name: row.name,
                    addList: [
                        {<!-- -->
                            yuanxi: "",

                            banji: '',
                            classesList: []

                        }
                    ]
                }
            }


        },
        removeOne(index) {<!-- -->
            this.form.addList.splice(index, 1)
        },
        plusOne() {<!-- -->
            this.form.addList.push(
                {<!-- -->
                    yuanxi: "",
                    // departmentList: [],
                    banji: '',
                    classesList: []
                }
            )
        },
        // Department
        department() {<!-- -->
            let params = {<!-- -->
                token: this.$store.state.Authorization,
                limit: 1000

            };
            departmentDepartmentList(params).then((res) => {<!-- -->
                let {<!-- --> data, code } = res;
                if (code == 200) {<!-- -->
                    this.departmentList = data.list


                }
            });

        },
        chooseClass(index) {<!-- -->
            this.form.addList[index].classesList = []
            this.form.addList[index].banji = ''

            this.classes(index)

        },
        classes(index) {<!-- -->
            let params = {<!-- -->
                token: this.$store.state.Authorization,
                limit: 1000,
                department: this.form.addList[index].yuanxi

            };
            departmentClassesList(params).then((res) => {<!-- -->
                let {<!-- --> data, code } = res;
                if (code == 200) {<!-- -->

                    this.form.addList[index].classesList = data.list

                }
            });

        },

    },
    created() {<!-- -->

    },
    mounted() {<!-- -->

    },
    beforeCreate() {<!-- --> },
    beforeMount() {<!-- --> },
    beforeUpdate() {<!-- --> },
    updated() {<!-- --> },
    beforeDestroy() {<!-- --> },
    destroyed() {<!-- --> },
    activated() {<!-- --> },
}
</script>