HTML开发 Vue2.x + Element-UI 动态生成表单项并添加表单校验

news2024/10/3 1:21:27

基于vue2.x 和element-ui 动态生成表单项并添加表单校验;

1、需求问题

如下图,项目有个需求,点击添加按钮,新增一行设备信息,且每项信息必填;

需求图片

2、代码

看到这个需求,首先想到要使用v-for的形式进行处理每一行设备信息;但是,之前没有搞过动态生成表单项并添加表单校验(最近几年又回归iOS开发,H5开发只是临时协助其他部门开发),自己先尝试写了下,但是表单校验死活不起作用;问了部门H5大佬,结果都是没有写过类似页面,怎么办,网上搜索呗;果然网上不少内容,但是在我项目中依旧是表单校验不起作用,只好一一尝试修改,最终搞定;

特别需要注意的一点是,想要其作用,不能直接给el-form直接添加rules,动态绑定,需要给具体el-form-item添加对应的rules

有效代码示例:

 <el-form ref="form" v-loading="isLoading" class="list-container" :model="form" label-width="0">
      <div v-for="(item, index) in form.devices" :key="index" class="list-item-container">
        <el-form-item :prop="'devices.' + index + '.name'" :rules="rules.name">
          <el-input v-model="item.name" class="list-item-input" size="small" maxlength="20" clearable placeholder="设备名称" />
        </el-form-item>
        <el-form-item :prop="'devices.' + index + '.quantity'" :rules="rules.quantity">
          <el-input v-model="item.quantity" class="list-item-input-samll" size="small" maxlength="20" clearable placeholder="设备数量" />
        </el-form-item>
        <el-form-item>
          <el-button class="danger" size="small" type="text" @click="handleDelete(index)">
            删除
          </el-button>
        </el-form-item>
      </div>
    </el-form>

无效代码示例:

 <el-form ref="form" v-loading="isLoading" class="list-container" :model="form" :rules="rules" label-width="0">
      <div v-for="(item, index) in form.devices" :key="index" class="list-item-container">
        <el-form-item :prop="'devices.' + index + '.name'">
          <el-input v-model="item.name" class="list-item-input" size="small" maxlength="20" clearable placeholder="设备名称" />
        </el-form-item>
        <el-form-item :prop="'devices.' + index + '.quantity'">
          <el-input v-model="item.quantity" class="list-item-input-samll" size="small" maxlength="20" clearable placeholder="设备数量" />
        </el-form-item>
        <el-form-item>
          <el-button class="danger" size="small" type="text" @click="handleDelete(index)">
            删除
          </el-button>
        </el-form-item>
      </div>
    </el-form>

废话少数,直接上成品代码;

<template>
  <div class="ledger-tab-page">
    <el-button type="primary" @click="handleAdd">{{ '添加' }}</el-button>
    <el-form ref="form" v-loading="isLoading" class="list-container" :model="form" label-width="0">
      <div v-for="(item, index) in form.devices" :key="index" class="list-item-container">
        <el-form-item :prop="'devices.' + index + '.name'" :rules="rules.name">
          <el-input v-model="item.name" class="list-item-input" size="small" maxlength="20" clearable placeholder="设备名称" />
        </el-form-item>
        <el-form-item :prop="'devices.' + index + '.quantity'" :rules="rules.quantity">
          <el-input v-model="item.quantity" class="list-item-input-samll" size="small" maxlength="20" clearable placeholder="设备数量" />
        </el-form-item>
        <el-form-item :prop="'devices.' + index + '.km_mileage'" :rules="rules.km_mileage">
          <span class="list-item-text">DK</span>
          <el-input v-model="item.km_mileage" class="list-item-input-samll" size="small" maxlength="3" clearable placeholder="安装里程" />
        </el-form-item>
        <el-form-item :prop="'devices.' + index + '.metre_mileage'" :rules="rules.metre_mileage">
          <span> + </span>
          <el-input v-model="item.metre_mileage" class="list-item-input-samll" size="small" maxlength="3" clearable placeholder="安装里程" />
        </el-form-item>
        <el-form-item :prop="'devices.' + index + '.validity_date'" :rules="rules.validity_date">
          <el-date-picker v-model="item.validity_date" type="datetime" size="small" class="list-item-date" placeholder="请选择有效期" default-time="00:00:00" />
        </el-form-item>
        <el-form-item>
          <el-button class="danger" size="small" type="text" @click="handleDelete(index)">
            删除
          </el-button>
        </el-form-item>
      </div>
    </el-form>
  </div>
</template>
<script>

import _ from 'lodash'

export default {

  components: {
    BwtButton
  },

  props: {
    info: {
      type: Array,
      default: () => {
        return []
      }
    }
  },

  data() {
    return {
      isLoading: false,
      form: {
        devices: []
      },
      rules: {
        // 'devices.*.name': [
        //   { required: true, message: '设备名称为必填项', trigger: 'blur' }
        // ],
        name: [
          { required: true, message: '设备名称为必填项', trigger: 'blur' }
        ],
        quantity: [
          { required: true, message: '设备数量为必填项', trigger: 'blur' },
          { type: 'number', message: '设备数量必须为数字', trigger: 'blur' },
          { pattern: /^[1-9]\d{0,3}$/, message: '请输入正确的设备数量', trigger: 'blur' }
        ],
        km_mileage: [
          { required: true, message: '安装里程为必填项', trigger: 'blur' },
          { type: 'number', message: '安装里程必须为数字', trigger: 'blur' },
          { pattern: /^[1-9]\d{0,2}$/, message: '请输入正确的里程范围', trigger: 'blur' }
        ],
        metre_mileage: [
          { required: true, message: '安装里程为必填项', trigger: 'blur' },
          { type: 'number', message: '安装里程必须为数字', trigger: 'blur' },
          { pattern: /^[1-9]\d{0,2}$/, message: '请输入正确的里程范围', trigger: 'blur' }
        ],
        validity_date: [
          { required: true, message: '请选择有效期', trigger: 'blur' }
        ]
      }
    }
  },
  computed: {
  },

  watch: {

    'info': function(newVal) {
      if (newVal) {
        // 处理详情回显
        this.form.devices = newVal || []
      }
    }
  },
  mounted() {
  },
  methods: {

    // 清空表单内容(供外部调用)
    resetFields() {
      this.form.devices = []
    },

    // 表单校验(供外部调用)
    formValidate() {
      // 校验:如果name为空,不允许提交
      return new Promise((resolve, reject) => {
        try {
          this.$refs.form.validate((valid) => {
            if (!valid) {
              this.$message.error('请完善设备信息')
            }
            resolve(valid)
          })
        } catch (error) {
          reject(error)
        }
      })
    },

    // 获取当前页面的表单数据
    formData() {
      return _.cloneDeep(this.form.devices)
    },

    // 新增
    handleAdd() {
      // 增加一行,
      const item = {
        name: '',
        quantity: '',
        km_mileage: '',
        metre_mileage: '',
        validity_date: ''
      }
      this.form.devices.push(item)
    },

    // 删除
    handleDelete(index) {
      this.form.devices.splice(index, 1)
    }
  }
}
</script>
<style scoped lang="scss">
.ledger-tab-page {
  margin: 20px 0;
  width: 100%;
}

.list-container {
  margin-top: 10px;
  max-height: 400px;
  overflow-y: auto !important;
}

.list-item-container {
  display: flex;
  width: 100%;
}

.list-item-input {
  width: 200px !important;
  margin-right: 10px;
}

.list-item-text {
  margin: 0 5px;
}

.list-item-input-samll {
  width: 100px !important;
  margin-right: 5px;
  margin-left: 5px;
}

.list-item-date {
  width: 200px !important;
  margin-right: 10px;
}

</style>

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

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

相关文章

python 巡检报告中的邮件处理

00.创作背景,在每天的巡检报告中要 要检查oa相关服务器的备份作业是否备份成功 那个备份软件有个功能&#xff0c;就是完成备份作业后&#xff0c;可以发送信息到我的邮箱。 01.通过检查我邮箱的信息&#xff0c;就可以了解那个备份作业的情况。 通过解释邮件的名称可以了解备…

618大促该买哪些数码好物?数码好物选购清单来啦,闭眼不踩坑!

618年中大促&#xff0c;无疑是一场数码爱好者的盛宴&#xff0c;在这个时刻&#xff0c;各大品牌和商家纷纷推出超值优惠&#xff0c;让众多心仪的数码产品以历史最低价呈现在消费者面前。面对如此丰富的选择&#xff0c;你是否也在犹豫哪些数码好物值得在这个节点入手呢&…

斯坦福 AI 团队被指抄袭清华大模型:细节揭秘

近日&#xff0c;斯坦福AI团队因发布的AI模型被指抄袭清华大学的研究成果而陷入争议。本文将详细探讨这一事件的背景、关键细节及其对开源社区的影响。 事件背景 斯坦福的AI团队发布了一个名为“LLaMA-3V”的模型&#xff0c;声称只花了500美元且只用了GPT-4的1%的体量便达到…

在Windows中使用svn的命令行

windows下使用svn命令行_svn命令行工具在哪里-CSDN博客 先下载命令行工具 再进行配置 set SVN_CMD_HOMEC:\Users\admin\Desktop\Apache-Subversion-1.14.0\bin(你的安装路径) set path%path%;%SVN_CMD_HOME% svn help查看svn版本 命令行查看svn版本--真实有效_svn 版本查看…

解决微信小程序分享按钮不可用

问题描述 在微信小程序中点击胶囊按钮上的三个点&#xff0c;在弹出的对话框中的【分享给好友】【分享到朋友圈】按钮都属于不可用的状态&#xff0c;显示未设置。 问题截图 解决方案 在每个需要此功能的页面都需要添加此代码&#xff0c;否则就不能进行使用。 // vue3时&l…

QT系列教程(8) QT 布局学习

简介 Qt 中的布局有三种方式&#xff0c;水平布局&#xff0c;垂直布局&#xff0c;栅格布局。 通过ui设置布局 我们先创建一个窗口应用程序&#xff0c;程序名叫layout&#xff0c;基类选择QMainWindow。但我们不使用这个mainwindow&#xff0c;我们创建一个Qt应用程序类Log…

LLM系列: LLama2

推理流程 从输入文本&#xff0c;到推理输出文本&#xff0c;LLama2模型处理流程如下&#xff1a; step1 Tokenization 输入数据&#xff1a;一个句子或一段话。通常表示成单词或字符序列。 Tokenization即对文本按单词或字符序列切分&#xff0c;形成Token序列。Token序列再…

跑mask2former(自用)

1. 运行docker 基本命令&#xff1a; sudo docker ps -a &#xff08;列出所有容器状态&#xff09; sudo docker run -dit -v /hdd/lyh/mask2former:/mask --gpus "device0,1" --shm-size 16G --name mask 11.1:v6 &#xff08;创建docker容器&…

RocketMQ教程(一):RocketMQ的基本概念

RocketMQ是什么? RocketMQ 是一个分布式消息中间件和流计算平台,由阿里巴巴团队开源并贡献给 Apache 软件基金会,现为 Apache 顶级项目。它主要用于处理大规模数据的传输问题,支持高吞吐量、高可用性和可扩展性的消息发布和订阅服务。RocketMQ 能够确保消息的可靠传输,支持…

C# Web控件与数据感应之 填充 HtmlTable

目录 关于 HtmlTable HtmlTable与BaseDataList的区别 准备数据源 ​范例运行环境 FillTable 方法 设计与实现 模板样例输出 Automatic 模式填充 ​ DynamicRows 模式填充 StaticRows 模式填充 ​ 小结 关于 HtmlTable 数据感应也即数据捆绑&#xff0c;是…

C语言指针与数组名的联系

目录 一、数组名的理解 a.数组名代表数组首元素的地址 b. 两个例外 二、使用指针来访问数组 三、一维数组传参的本质 一、数组名的理解 a.数组名代表数组首元素的地址 我们在使用指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,…

智慧园区智能化系统整体解决方案(111页PPT)

方案介绍&#xff1a; 智慧园区智能化系统整体解决方案是一个综合性的管理平台&#xff0c;它通过集成视频、报警、园区一卡通、产线管理、能耗管理、公共广播、信息发布等多种系统&#xff0c;实现园区的全方位智能化管理。该系统以基础管理平台为系统基础&#xff0c;提供系…

TPM 是什么?如何查看电脑的 TPM?

TPM 是什么&#xff1f; 首先我们来了解一下 TPM 是什么&#xff0c;TPM 由可信计算组织&#xff08;Trusted Computing Group&#xff0c;TCG&#xff09;开发&#xff0c;为了在提高计算机系统的安全性。随着网络安全威胁的不断增加&#xff0c;TPM 技术逐渐成为确保系统安全…

git-生成SSH密钥

git-生成SSH密钥 1 打开命令窗口2 操作 1 打开命令窗口 选择"Git Bash Here"&#xff0c;打开Git命令窗口 2 操作 查看当前用户名称 git config user.name配置你的邮箱&#xff0c;“6xxxqq.com” 填写自己的邮箱 git config --global user.email "6xxxqq…

【Oracle篇】rman全库异机恢复:从RAC环境到单机测试环境的转移(第四篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

STC90C51驱动LCD1602、LCD12864、OLED

主控芯片&#xff08;STC90C516RDPG5151028&#xff09;介绍 ROM64K,RAM1280字节&#xff0c;40Pin&#xff0c;3个定时器&#xff0c;1个串口&#xff0c;8个中断源&#xff08;分别是&#xff1a;外部中断0(INTO)、外部中断 1(INT1)、外部中断 2(INT2)、外部中断 3(INT3)、定…

线性dp+数论分块,1561D1 - Up the Strip

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1561D1 - Up the Strip (simplified version) 二、解题报告 1、思路分析 一眼dp 写出dp方程&#xff1a; 前者维护前缀和即可O(1)转移 后者呢&#xff1f;——整除分块数论分块问题-CSDN博客 简单叙述下…

Mongodb的数据库简介、docker部署、操作语句以及java应用

Mongodb的数据库简介、docker部署、操作语句以及java应用 本文主要介绍了mongodb的基础概念和特点&#xff0c;以及基于docker的mongodb部署方法&#xff0c;最后介绍了mongodb的常用数据库操作语句&#xff08;增删改查等&#xff09;以及java下的常用语句。 一、基础概念 …

Technart电动螺丝刀TN101控制器维修

Technart电动螺丝刀以其高效、稳定和精确的扭矩控制而闻名。然而&#xff0c;即使优质的产品&#xff0c;在长时间的使用下&#xff0c;也可能会出现TECHNART电动螺母扳手控制器故障。 常见故障及维修方法 1. 控制器不工作 症状&#xff1a;电动螺丝刀无法启动&#xff0c;或启…

sql注入-布尔盲注

布尔盲注&#xff08;Boolean Blind SQL Injection&#xff09;是一种SQL注入攻击技术&#xff0c;用于在无法直接获得查询结果的情况下推断数据库信息&#xff1b;它通过发送不同的SQL查询来观察应用程序的响应&#xff0c;进而判断查询的真假&#xff0c;并逐步推断出有用的信…