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

多个表单使用相同的 ref 和 rules,表单验证规则不生效

在 Vue 和 Element UI 中,如果多个表单使用相同的 ref 和 rules,可能会导致表单验证规则不生效。这是因为 ref 是唯一的,多个表单共享同一个 ref 会导致冲突。

解决方法:

1. 为每个表单设置不同的 ref

为每个表单设置不同的 ref,并在验证时分别调用各自的验证方法。

示例代码:
<template>
  <div>
    <!-- 表单 1 -->
    <el-form :model="form1" :rules="rules" ref="form1Ref">
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form1.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('form1Ref')">提交表单 1</el-button>
      </el-form-item>
    </el-form>

    <!-- 表单 2 -->
    <el-form :model="form2" :rules="rules" ref="form2Ref">
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form2.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('form2Ref')">提交表单 2</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form1: { name: "" }, // 表单 1 数据
      form2: { name: "" }, // 表单 2 数据
      rules: {
        name: [
          { required: true, message: "请输入姓名", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    // 提交表单
    submitForm(formRef) {
      this.$refs[formRef].validate((valid) => {
        if (valid) {
          alert("表单验证通过");
        } else {
          alert("表单验证失败");
          return false;
        }
      });
    },
  },
};
</script>
说明:
  • 为每个表单设置不同的 ref(如 form1Ref 和 form2Ref)。

  • 在 submitForm 方法中,通过动态传入 ref 名称来验证对应的表单。


2. 使用动态 ref

如果表单是动态生成的(例如通过 v-for 循环),可以使用动态 ref

示例代码:
<template>
  <div>
    <!-- 动态生成表单 -->
    <el-form
      v-for="(form, index) in forms"
      :key="index"
      :model="form"
      :rules="rules"
      :ref="`formRef${index}`"
    >
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm(index)">提交表单 {{ index + 1 }}</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      forms: [
        { name: "" }, // 表单 1 数据
        { name: "" }, // 表单 2 数据
      ],
      rules: {
        name: [
          { required: true, message: "请输入姓名", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    // 提交表单
    submitForm(index) {
      this.$refs[`formRef${index}`][0].validate((valid) => {
        if (valid) {
          alert(`表单 ${index + 1} 验证通过`);
        } else {
          alert(`表单 ${index + 1} 验证失败`);
          return false;
        }
      });
    },
  },
};
</script>
说明:
  • 使用 v-for 动态生成表单,并为每个表单设置动态 ref(如 formRef0formRef1)。

  • 在 submitForm 方法中,通过索引动态获取对应的表单 ref


3. 共享 rules 但独立验证

如果多个表单共享相同的验证规则,可以将 rules 提取到公共位置,但为每个表单设置独立的 ref 和验证逻辑。

<template>
  <div>
    <!-- 表单 1 -->
    <el-form :model="form1" :rules="rules" ref="form1Ref">
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form1.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="validateForm('form1Ref')">验证表单 1</el-button>
      </el-form-item>
    </el-form>

    <!-- 表单 2 -->
    <el-form :model="form2" :rules="rules" ref="form2Ref">
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form2.name"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="validateForm('form2Ref')">验证表单 2</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form1: { name: "" }, // 表单 1 数据
      form2: { name: "" }, // 表单 2 数据
      rules: {
        name: [
          { required: true, message: "请输入姓名", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    // 验证表单
    validateForm(formRef) {
      this.$refs[formRef].validate((valid) => {
        if (valid) {
          alert("表单验证通过");
        } else {
          alert("表单验证失败");
          return false;
        }
      });
    },
  },
};
</script>
说明:
  • 共享 rules,但为每个表单设置独立的 ref

  • 在 validateForm 方法中,通过动态传入 ref 名称来验证对应的表单。


总结

  • 如果多个表单共享相同的 ref,会导致冲突,验证规则不生效。

  • 解决方法:

    1. 为每个表单设置不同的 ref

    2. 如果表单是动态生成的,使用动态 ref

    3. 共享 rules,但独立验证每个表单。

 

4.同步验证多个表单实现思路:

  1. 为每个表单设置独立的 ref

    • 每个表单需要有一个唯一的 ref,以便能够单独访问和验证。

  2. 使用 Promise.all 进行同步验证

    • 将每个表单的验证方法包装成 Promise,然后使用 Promise.all 等待所有表单验证完成。

  3. 处理验证结果

    • 如果所有表单验证通过,执行后续逻辑;如果有表单验证失败,提示错误信息。


示例代码:
<template>
  <div>
    <!-- 表单 1 -->
    <el-form :model="form1" :rules="rules" ref="form1Ref">
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form1.name"></el-input>
      </el-form-item>
    </el-form>

    <!-- 表单 2 -->
    <el-form :model="form2" :rules="rules" ref="form2Ref">
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="form2.email"></el-input>
      </el-form-item>
    </el-form>

    <!-- 提交按钮 -->
    <el-button type="primary" @click="validateAllForms">提交所有表单</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form1: { name: "" }, // 表单 1 数据
      form2: { email: "" }, // 表单 2 数据
      rules: {
        name: [
          { required: true, message: "请输入姓名", trigger: "blur" },
        ],
        email: [
          { required: true, message: "请输入邮箱", trigger: "blur" },
          { type: "email", message: "请输入正确的邮箱地址", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    // 验证单个表单
    validateForm(formRef) {
      return new Promise((resolve, reject) => {
        this.$refs[formRef].validate((valid) => {
          if (valid) {
            resolve(); // 验证通过
          } else {
            reject(new Error(`表单 ${formRef} 验证失败`)); // 验证失败
          }
        });
      });
    },

    // 同步验证所有表单
    async validateAllForms() {
      try {
        // 使用 Promise.all 同步验证所有表单
        await Promise.all([
          this.validateForm("form1Ref"),
          this.validateForm("form2Ref"),
        ]);
        alert("所有表单验证通过");
        // 在这里执行提交逻辑
      } catch (error) {
        alert(error.message); // 提示错误信息
      }
    },
  },
};
</script>

代码说明:
  1. validateForm 方法

    • 将表单验证包装成 Promise,验证通过时调用 resolve,验证失败时调用 reject

  2. validateAllForms 方法

    • 使用 Promise.all 同步验证所有表单。

    • 如果所有表单验证通过,执行后续逻辑(如提交数据)。

    • 如果有表单验证失败,捕获错误并提示用户。

  3. 表单 ref

    • 每个表单需要设置唯一的 ref(如 form1Ref 和 form2Ref)。


动态表单的同步验证

如果表单是动态生成的(例如通过 v-for 循环),可以使用动态 ref 和 Promise.all 实现同步验证。

示例代码:
<template>
  <div>
    <!-- 动态生成表单 -->
    <el-form
      v-for="(form, index) in forms"
      :key="index"
      :model="form"
      :rules="rules"
      :ref="`formRef${index}`"
    >
      <el-form-item label="姓名" prop="name">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
    </el-form>

    <!-- 提交按钮 -->
    <el-button type="primary" @click="validateAllForms">提交所有表单</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      forms: [
        { name: "" }, // 表单 1 数据
        { name: "" }, // 表单 2 数据
      ],
      rules: {
        name: [
          { required: true, message: "请输入姓名", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    // 验证单个表单
    validateForm(formRef) {
      return new Promise((resolve, reject) => {
        this.$refs[formRef][0].validate((valid) => {
          if (valid) {
            resolve(); // 验证通过
          } else {
            reject(new Error(`表单 ${formRef} 验证失败`)); // 验证失败
          }
        });
      });
    },

    // 同步验证所有表单
    async validateAllForms() {
      try {
        // 动态生成验证任务
        const validationTasks = this.forms.map((_, index) =>
          this.validateForm(`formRef${index}`)
        );
        // 使用 Promise.all 同步验证所有表单
        await Promise.all(validationTasks);
        alert("所有表单验证通过");
        // 在这里执行提交逻辑
      } catch (error) {
        alert(error.message); // 提示错误信息
      }
    },
  },
};
</script>

总结

  • 使用 Promise.all 可以同步验证多个表单。

  • 每个表单需要设置唯一的 ref,并通过 validate 方法进行验证。

  • 动态表单可以通过动态 ref 和 Promise.all 实现同步验证。

 


http://www.kler.cn/a/501483.html

相关文章:

  • 系统看门狗配置--以ubuntu为例
  • ubuntu官方软件包网站 字体设置
  • 校园跑腿小程序---轮播图,导航栏开发
  • STM32-笔记39-SPI-W25Q128
  • 计算机网络 (33)传输控制协议TCP概述
  • Gitlab-Runner配置
  • 前端开发:Web前端和HTML
  • Flutter 3.x 版本升级实战:让老项目焕发新生
  • 深入理解 Spring MVC 中的 @ModelAttribute 注解
  • 【Python学习系列】数据类型(二)
  • 《DOM NodeList》
  • Openstack持久存储-Swift,Cinder,Manila三者之间的区别
  • 【对象存储】-- s3:\\、s3n:\\、s3a:\\ 简介
  • 力扣 岛屿数量
  • 在线游戏靶场【overthewire.org】之linux基础练兵场
  • Github 2025-01-09 Go开源项目日报 Top10
  • docker--小白--导入timescaledb
  • 使用 WPF 和 C# 绘制图形
  • 稀疏编码 (Sparse Coding) 算法详解与PyTorch实现
  • linux:文件的创建/删除/复制/移动/查看/查找/权限/类型/压缩/打包
  • Android RIL(Radio Interface Layer)全面概述和知识要点(3万字长文)
  • webpack常见优化方法
  • 2024信息安全网络安全等安全意识(附培训PPT下载)
  • Go语言开发高效的RPC服务的方法
  • 基于nginx实现正向代理(linux版本)
  • C#/.NET/.NET Core技术前沿周刊 | 第 20 期(2025年1.1-1.5)