vue3 +elementplus | vue2+elementui 动态地通过验证规则子新增或删除单个表单字段

news2024/12/23 6:54:05

效果图
在这里插入图片描述
点击 ‘+’ 新增一行,点击‘-’ 删除一行

vue3+elementplus写法

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="教师编号:" prop="code" :rules="[{ required: true, message: '请输入教师编号', trigger: 'blur' },
                { min: 4, message: '长度不能少于四位', trigger: 'blur' }]">
                    <el-input v-model="form.code" />
                </el-form-item>
                <el-form-item label="教师姓名:" prop="name" :rules="[{ required: true, message: '请输入教师姓名', trigger: 'blur' }]">
                    <el-input v-model="form.name" />
                </el-form-item>
                <div v-for="(item, index) in form.addList" :key="item.key" flex>
                    <!--注意:官方给的例子是用form的addList 去作为prop的标记  -->
                    <el-form-item label="授课院系:" :prop="'addList.' + index + '.yuanxi'" :rules="{
                        required: true,
                        message: '授课院系不能为空',
                        trigger: 'change',
                    }">
                        <el-select v-model="item.yuanxi" placeholder="请选择" @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="授课班级:" :prop="'addList.' + index + '.banji'" :rules="{
                        required: true,
                        message: '授课班级不能为空',
                        trigger: 'change',
                    }">
                        <el-select v-model="item.banji" placeholder="请选择">
                            <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)">提交
                    </el-button>
                    <el-button @click="resetForm(ruleFormRef)">重置</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


        }
    });
}
// 第二部:暴露方法
defineExpose({
    showDio1
})
onMounted(() => {
    department()
})
</script>

vue2+elementui 写法

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="教师编号:" prop="code" :rules="[
                        { required: true, message: '请输入教师编号', trigger: 'blur' },
                        { min: 4, message: '长度不能少于四位', trigger: 'blur' }
                    ]">
                        <el-input v-model="form.code" onkeyup="value=value.replace(/[\W]/g,'')"
                            placeholder="请输入教师编号"></el-input>
                    </el-form-item>
                    <el-form-item label="教师姓名:" prop="name" :rules="[
                        { required: true, message: '请输入教师姓名', trigger: 'blur' }
                    ]">
                        <el-input v-model="form.name" type="text" @input="
                            form.name = form.name.replace(
                                /[^\u4E00-\u9FA5]/g,
                                ''
                            )
                            " placeholder="请输入教师姓名"></el-input>
                    </el-form-item>
                    <div flex v-for="(item, index) in form.addList" :key="index">
                        <el-form-item label="授课院系:" :prop="'addList.' + index + '.yuanxi'" :rules="{
                            required: true, message: '授课院系不能为空', trigger: 'change'
                        }">
                            <el-select v-model="item.yuanxi" filterable placeholder="请选择" @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="授课班级:" :prop="'addList.' + index + '.banji'" :rules="{
                            required: true, message: '授课班级不能为空', trigger: 'change'
                        }">
                            <div flex="cross:center">
                                <el-select v-model="item.banji" filterable placeholder="请选择"
                                    @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')">提交</el-button>
                <el-button class="dioSave btnCancel dioBigSave" @click="resetForm1" v-if="flag == 0">重置</el-button>
                <el-button class="dioSave btnCancel dioBigSave" @click="resetForm1" v-if="flag == 1">重置</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('新增成功!')
                    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('编辑成功!')
                    this.form.code = ''
                    this.form.name = ''
                    this.form.addList = [
                        {
                            yuanxi: "",

                            banji: '',
                            classesList: []

                        }
                    ]

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

                }
            });
        },
        closeDio() {
            console.log('执行');
            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() {
            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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1045377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

强势得分套路之一:单基因泛癌+实验验证

今天给同学们分享一篇单基因泛癌实验验证的生信文章“A human pan-cancer system analysis of heat shock protein family A member 5”&#xff0c;这篇文章于2023年5月15日发表在Am J Cancer Res期刊上&#xff0c;影响因子为5.2。 热休克蛋白家族A成员5&#xff08;HSPA5&am…

2024年湖北中级工程师职称申报需要准备什么资料呢?

湖北中级职称申报每个地方需要的资料和要求都不一样&#xff0c;但是大部分申报材料、条件和要求基本是一致的&#xff0c;有的只是细微差别。那么湖北中级工程师职称申报需要准备什么资料呢&#xff1f;今天甘建二先告诉你&#xff0c;职称资料需要提早准备哟&#xff0c;有的…

command not found

一 问题 连着几次登录&#xff0c;输入ls&#xff0c;都not found 二 解决方案 1. 临时生效&#xff0c;下次登录还是not found export PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin 2. 永久生效&#xff0c;将上面的配置&#xff0c;添加…

iTunes怎么用?iTunes如何恢复备份?(果粉必备教程)

iTunes是由苹果公司推出的一款免费数字媒体播放应用软件。通过使用iTunes软件&#xff0c;用户可以在软件上管理和播放数字音乐、视频、电影&#xff0c;以及电视节目等等。此外&#xff0c;iTunes还是管理数据的好帮手&#xff0c;用户可以通过iTunes备份管理自己手机上的数据…

“TaiChiHealthPreservation“ app Tech Support(URL)

If you have any questions, you can either leave a message or send the questions to our email address. We will answer them for you in the first time. Address: drrjownbnhotmail.com thank you.

机器人过程自动化(RPA)入门 4. 数据处理

到目前为止,我们已经了解了RPA的基本知识,以及如何使用流程图或序列来组织工作流中的步骤。我们现在了解了UiPath组件,并对UiPath Studio有了全面的了解。我们用几个简单的例子制作了我们的第一个机器人。在我们继续之前,我们应该了解UiPath中的变量和数据操作。它与其他编…

“智”造未来,江西同为科技(TOWE)参展第四届广州“两交会”圆满落幕

2023年9月13日—15日&#xff0c;由全国工商联科技装备业商会主办的第四届“两交会”&#xff08;广州两用技术装备成果交易会&#xff09;在广州广交会展馆圆满举行。本次展会以市场为主导&#xff0c;以需求为牵引&#xff0c;围绕相关单位“作训、后勤、装备”任务&#xff…

一文教你学会ArcGIS Pro地图设计与制图系列全流程(3)

ArcGIS Pro做的成果图及系列文章目录&#xff1a; 系列文章全集&#xff1a; 《一文教你学会ArcGIS Pro地图设计与制图系列全流程&#xff08;1&#xff09;》《一文教你学会ArcGIS Pro地图设计与制图系列全流程&#xff08;2&#xff09;》《一文教你学会ArcGIS Pro地图设计与…

喜讯 | 怿星科技获评SAE“优秀核心零部件企业”,测试软件平台工具广受赞誉

2023年9月22日-23日&#xff0c;SAE 2023汽车智能与网联技术国际学术会议成功举行。此次学术会议由SAE International与南昌智能新能源汽车研究院联合主办&#xff0c;大会汇聚了来自国内外智能网联领域的顶尖专家和学者。大会同期颁布的奖项旨在向行业推选出更多新时代涌现的杰…

人人都是项目经理-项目管理概述(一)

一、重新认识项目管理 1. 什么是项目 项目&#xff08;Project&#xff09;&#xff0c;是为提供某项独特的产品&#xff08;交付物&#xff09;&#xff0c;服务或成果所做的临时性努力。 – PMBOK指南 项目是指一系列独特的、复杂的并相互关联的活动&#xff0c;这些活动有着…

4、ARM异常处理

一、异常处理 1、异常 概念 处理器在正常执行程序的过程中可能会遇到一些不正常的的事件发生&#xff0c;这时处理器就要将当前的程序暂停下来转去处理这个异常的事件&#xff0c;异常事件完成后再返回到之前被异常打断的点继续执行 2、异常处理机制 不同的处理器对异常的…

Pandas行列转换

一、问题描述 在实际的数据处理过程中&#xff0c;常常会遇到需要将DataFrame中的列转换为行或将行转换为列的情况。但是&#xff0c;如果使用传统的Python方法&#xff0c;这种操作会非常繁琐且容易出错。因此&#xff0c;我们可以使用pandas库提供的优雅方式来完成列转行或行…

RDMA操作类型(三)

Send操作 引用一下&#xff0c;IB协议第9.4.1章节原文&#xff1a; The SEND Operation is sometimes referred to as a Push operation or as having channel semantics. Both terms refer to how the SW client of the transport service views the movement of data. With …

uni-app:canvas-绘制图形4(获取画布宽高,根据画布宽高进行图形绘制)

效果 代码 var width ; var height ; const query uni.createSelectorQuery(); //获取宽度 query.select(#firstCanvas).fields({ size: true }, (res) > { width res.width; height res.height; }).exec(); console.log(宽度width); console.log(高…

代码随想录算法训练营 动态规划part04

一、动态规划&#xff1a;01背包理论基础 挺详细的代码随想录 (programmercarl.com) 二、动态规划&#xff1a;01背包理论基础&#xff08;滚动数组&#xff09; 代码随想录 (programmercarl.com) 三、 分割等和子集 416. 分割等和子集 - 力扣&#xff08;LeetCode&#x…

软件安全测试和渗透测试有什么区别和联系?

随着网络攻击和数据泄露事件的频繁发生&#xff0c;软件系统的安全性已成为用户和企业关注的重要问题。通过进行软件安全测试和渗透测试&#xff0c;可以有效地发现和修复系统中的潜在漏洞和安全隐患&#xff0c;提高系统的抵御能力和可靠性。这不仅可以保护用户的隐私和数据安…

C语言进阶第四课-----------指针的进阶----------指针和数组笔试解释

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

手把手教你集成环信ReactNative离线推送

前言&#xff1a;在集成ReactNative推送之前&#xff0c;需要了解ReactNative与Android原生交互 一、RN与Android原生交互 RN给原生传递参数 步骤&#xff1a; 1.用Android Studio打开一个已经存在的RN项目&#xff0c;即用AS打开 项目文件夹/android,如下图所示 2.在An…

如何将微信、支付宝、字节等小程序直接迁移到自有app中

简要回顾一下 FinClip Studio 的相关能力&#xff1a; FinClip Studio 是一款强大的小程序云端容器&#xff0c;它可以将小程序嵌入到您的原生 App 中&#xff0c;实现无缝的融合体验。不仅如此&#xff0c;FinClip 还提供了一系列的工具和功能&#xff0c;以简化小程序的开发…

大模型训练之加速篇 -> peft(Lora) -> accelerator -> deepspeed (Zero)

HUGGINFACE PEFT库&#xff1a; 实现LORA&#xff0c; prefix-tuning. prompttuning, AdaLoRA, LLaMA-Adapter训练的库 HUGGINFACE accelerator库&#xff1a; 是一个将pytorch模型迁移到CPU/GPU/Multi-GPUs/TPU/Fp16/bf16模式下训练的一个标准库 DeepSpeed Pytorch的分布式并…