当前位置: 首页 > news >正文

动态循环表单+动态判断表单类型+动态判断表单是否必填方法

页面效果:

接口请求到的数据格式:

        list: [
                {
                    demandType: "设备辅助功能要求",
                    demandSettingList: [
                        {
                            id: "1907384788664963074",
                            name: "测试表单",
                            fieldType: 0,
                            contentValue: "",
                            vaildStatus: 0, // 0 非必填;1 必填
                        }
                    ]
                },
                {
                    demandType: "与产品接触部件要求",
                    demandSettingList: [
                        {
                            id: "1907384788648185858",
                            name: "需求背景",
                            fieldType: 0,
                            contentValue: "",
                            vaildStatus: 1
                        }
                    ]
                },
            ]

模版代码:

            <div v-for="(item,index) in list" :key="index">
                <el-form :inline="true" :model="item" :ref="'form' + index" label-width="100px">
                    <div class="demand-type">{{ item.demandType }}</div>
                    <div v-for="(itm,index2) in item.demandSettingList" :key="index2">
                        <!-- fieldType: 0---文本类型表单 -->
                        <el-form-item :label="itm.name" v-if="itm.fieldType === 0" :prop="'demandSettingList.' + index2 + '.contentValue'" 
                        :rules="{ required: itm.vaildStatus === 1, message: itm.name + '不能为空', trigger: 'blur' }">
                            <el-input v-model="itm.contentValue" placeholder="请输入" style="width:200px"></el-input>
                        </el-form-item>
                        <!-- fieldType: 1---数字类型表单 -->
                        <el-form-item :label="itm.name" v-if="itm.fieldType === 1" :prop="'demandSettingList.' + index2 + '.contentValue'" 
                        :rules="{ required: itm.vaildStatus === 1 }">
                            <el-input-number v-model="itm.contentValue" :min="1" style="width:200px"></el-input-number>
                        </el-form-item>
                        <!-- fieldType: 2---日期类型表单 -->
                        <el-form-item :label="itm.name" v-if="itm.fieldType === 2" :prop="'demandSettingList.' + index2 + '.contentValue'" 
                        :rules="{ required: itm.vaildStatus === 1 }">
                            <el-date-picker v-model="itm.contentValue" type="date" placeholder="请选择日期"
                                    format="yyyy-MM-dd" value-format="yyyy-MM-dd" style="width:200px">
                            </el-date-picker>
                        </el-form-item>
                        <!-- fieldType: 3---时间类型表单 -->
                        <el-form-item :label="itm.name" v-if="itm.fieldType === 3" :prop="'demandSettingList.' + index2 + '.contentValue'" 
                        :rules="{ required: itm.vaildStatus === 1 }">
                            <el-date-picker v-model="itm.contentValue" type="datetime" style="width:200px"
                            format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择时间"></el-date-picker>
                        </el-form-item>
                        <!-- fieldType: 4---人员单选类型表单 -->
                        <el-form-item :label="itm.name" v-if="itm.fieldType === 4" :prop="'demandSettingList.' + index2 + '.contentValue'" 
                        :rules="{ required: itm.vaildStatus === 1 }">
                            <el-select v-model="itm.contentValue" filterable remote placeholder="请选择" style="width:200px"
                                @focus="userFoucs" :remote-method="remoteMethod" :loading="loadingSearch">
                                <el-option v-for="it in searchUserList" :key="it.id" :label="`${it.realName}(${it.account})`"
                                    :value="it.id">
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <!-- fieldType: 5---人员多选类型表单 -->
                        <el-form-item :label="itm.name" v-if="itm.fieldType === 5" :prop="'demandSettingList.' + index2 + '.contentValue'" 
                        :rules="{ required: itm.vaildStatus === 1 }">
                            <el-select v-model="itm.contentValue" filterable remote placeholder="请选择" style="width:200px"
                                multiple collapse-tags @focus="userFoucs" :remote-method="remoteMethod" :loading="loadingSearch">
                                <el-option v-for="it in searchUserList" :key="it.id" :label="`${it.realName}(${it.account})`"
                                    :value="it.id">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </div>
                </el-form>
            </div>
            <div style="text-align: center;display: block;" v-if="rightFormList.length != 0">
                <el-button type="primary" @click="submitForm()" :loading="loadingBtn">确定</el-button>
            </div>

提交时的校验方法:

        submitForm() {
            this.$nextTick(() => {
                const formRefs = Object.values(this.$refs)
                    .flat()
                    .filter(ref => ref && typeof ref.validate === "function"); // 过滤非 el-form 组件

                if (formRefs.length === 0) {
                    console.warn("未找到任何 el-form 组件,请检查 v-for 绑定的 ref 是否正确");
                    return;
                }

                Promise.all(formRefs.map(form => form.validate()))
                    .then(() => {
                        this.loadingBtn = false;
                        let list = [];
                        this.rightFormList.forEach(item => {
                            item.demandSettingList.forEach(itm => {
                                list.push(itm);
                            });
                        });
                        return api.queryProjectDemandSettingUpdate(list, this.uuId);
                    })
                    .then(() => {
                        this.$message.success('操作成功!');
                        this.getRightList();
                        this.getUuid();
                    })
                    .catch(() => {
                        this.loadingBtn = false;
                        this.$message.warning("请完整填写必填信息!");
                    });
            });
        },

📌 总结

📢 代码执行流程

  1. 使用 this.$nextTick() 确保 this.$refs 获取到最新的 el-form 组件

  2. 收集 this.$refs 里的 el-form 组件,并确保 .validate() 方法存在

  3. Promise.all() 让所有表单执行 .validate()

    • 如果全部校验通过,调用 API 提交数据。

    • 如果有未填写的必填项,则提示用户补充信息。

🛠 可能的问题

validate is not a function

原因

  • this.$refs["form" + index] 可能是 数组undefined

  • 解决方案

    • 使用 this.$refs["form" + index][0] 或者 遍历 this.$refs 过滤非 el-form 组件(即代码里 .filter(ref => typeof ref.validate === "function") 部分)。

❌ 提交后还是提示“请完整填写必填信息”

可能原因

  • el-form-item:prop 绑定错误,导致 validate() 无法正确校验。

  • v-model 绑定的 contentValue 可能是 undefined,导致 required 校验失败。

检查方案

  1. 确保 el-form-item:prop 写对:

    <el-form-item :prop="'demandSettingList.' + index2 + '.contentValue'"
  2. 确保 itm.contentValue 初始值是 ""null(不要是 undefined)。

至此完成!!!

测试有效!!!感谢支持!!!


文章转载自:
http://actinomycin.lbooon.cn
http://betrayer.lbooon.cn
http://bihar.lbooon.cn
http://besmear.lbooon.cn
http://casually.lbooon.cn
http://catfoot.lbooon.cn
http://australopithecine.lbooon.cn
http://assistantship.lbooon.cn
http://auspice.lbooon.cn
http://affirmably.lbooon.cn
http://backstabber.lbooon.cn
http://carphology.lbooon.cn
http://cert.lbooon.cn
http://chaotic.lbooon.cn
http://adjournment.lbooon.cn
http://chanceless.lbooon.cn
http://bioceramic.lbooon.cn
http://boogeyman.lbooon.cn
http://carnification.lbooon.cn
http://asonant.lbooon.cn
http://admeasure.lbooon.cn
http://ascomycetous.lbooon.cn
http://anguine.lbooon.cn
http://approbatory.lbooon.cn
http://bleu.lbooon.cn
http://baboosh.lbooon.cn
http://censorship.lbooon.cn
http://burundi.lbooon.cn
http://canalise.lbooon.cn
http://afrikanerdom.lbooon.cn
http://www.dtcms.com/a/110350.html

相关文章:

  • 基于Deepface的情绪识别c++
  • HOW - Axios 拦截器特性
  • 量子芯火燎原:AI算力革命的密码
  • RabbitMQ高级特性1
  • Ubuntu 24 云服务器上部署网站_详细版_1
  • 关于c++ trt推理YOLO系列,出现检测框混乱,集中左上角的问题
  • git技法-对比master和release两个版本差异提交
  • 搭建redis遇到问题:
  • PVE如何查看某块硬盘被哪些虚拟机使用
  • 使用axios发请求
  • 华为项目管理“六步一法”方法论全解析:目标确认、项目活动分解与日事清系统协同
  • 基于51单片机的贪吃蛇小游戏proteus仿真
  • 通过 C# 提取PDF文档中的图片
  • C++ | 文件读写(ofstream/ifstream/fstream)
  • 谷歌TV认证,谷歌TADA认证,谷歌电视认证介绍
  • C++ | 类模板
  • DBAPI设置服务器开机自启动
  • DeepSeek 助力心理医生小程序赋能!心理咨询小程序 线上咨询平台搭建
  • 如何保障话费api接口的稳定性?
  • 最新扣子(Coze)案例教程:最新抖音视频文案提取方法替代方案,音频视频提取文案插件制作,手把手教学,完全免费教程
  • 基于web的生产过程执行管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 解决docker部署的容器第二天访问报错139的问题
  • 高密度任务下的挑战与破局:数字样机助力火箭发射提效提质
  • C#:接口(interface)
  • 【vue3】黑马小兔鲜儿项目uniapp navigationStyle
  • 常用学术期刊/会议查询工具
  • LiveData 和 MutableLiveData 的区别
  • SQL Server 2022 读写分离问题整合
  • 如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
  • 基于 C# 开发视觉检测系统项目全解析