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

基于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.mfbz.cn/a/693812.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大众汽车裁员加速,38万元遣散费起步

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 几周前&#xff0c;大众汽车宣布了一项新的裁员计划。 一、裁员行动与额外福利并行 大众汽车近期在裁员行动上取得了显著进展&#xff0c;其遣散…

基于I2C协议的OLED显示(利用U82G库)

目录 一、I2C协议的基本原理和时序协议I2C通信协议的原理I2C时序基本单元I2C时序 二、建立工程RCC配置TIM1配置时钟树配置工程配置 三、U8g2移植精简u8g2_d_setup.c精简u8g2_d_memory.c编写移植函数stm32_u8g2.hstm32_u8g2.c 四、实验1.U82G的demo例程2.显示网名昵称中文取模步…

Pytorch 从零实现 Transformer

前言 之前虽然了解过 Transformer 架构&#xff0c;但是没有自己实现过。 最近阅读 transformers 库中 Llama 模型结构&#xff0c;于是想试着亲手实现一个简单的 Transformer。 在实现过程中加深了理解&#xff0c;同时发现之前阅读 Llama 中一些错误的地方&#xff0c;因此…

蓝桥杯--跑步计划

问题描述 小蓝计划在某天的日期中出现 11 时跑 55 千米&#xff0c;否则只跑 11 千米。注意日期中出现 11 不仅指年月日也指星期。 请问按照小蓝的计划&#xff0c;20232023 年小蓝总共会跑步锻炼多少千米?例如&#xff0c;55 月 11 日、11 月 1313 日、1111 月 55 日、44 月…

Linux:基本指令

文章目录 ls指令pwd指令cd指令touch指令mkdir指令rmdir指令 && rm指令cp指令man指令echo指令输出重定向追加重定向 cat指令输入重定向 mv指令which指令alias指令more && less指令head && tail指令事件相关的指令date显示时间戳 cal指令find指令grep指令…

c++之旅第十弹——IO流

大家好啊&#xff0c;这里是c之旅第十弹&#xff0c;跟随我的步伐来开始这一篇的学习吧&#xff01; 如果有知识性错误&#xff0c;欢迎各位指正&#xff01;&#xff01;一起加油&#xff01;&#xff01; 创作不易&#xff0c;希望大家多多支持哦&#xff01; 一.流的概念&…

星火秘境游戏开发链游app定制开发源码部署

星火秘境是一款神秘而充满冒险的游戏&#xff0c;开发这样一款游戏需要综合考虑多个方面&#xff0c;包括游戏设计、美术设计、程序开发、音效制作等。下面我将简要介绍一下游戏开发和链游app搭建的一般流程&#xff1a; 游戏设计&#xff1a; 确定游戏类型&#xff1a;星火秘…

雷电模拟器中控实现,直通源码

目录 前言 开发 需求 初始环境 UI搭建 功能实现 前言 本篇为易语言雷电模拟器中控项目实现操作&#xff0c;一般用于&#xff1a;脚本开发多线程模拟操作等起始模板框架&#xff0c;使用易语言原因为其前后端一体化&#xff0c;对于脚本开发而言更为方便。 开发 需求 以…

每天壁纸不重样~下载必应每日图片

下载必应每日图片 必应不知道你用过没有你下载过必应的图片没有你又没搜索过桌面图片你是不是安装过桌面图片软件你是不是为找一个好看的图片下载过很多桌面软件 必应每日图片 必应每天都会有一张不同的风景图片&#xff0c;画质清晰&#xff0c;而且不收费可以下载使用 但…

MySQL之多表查询—列子查询

一、引言 标量子查询上篇博客已学习。接下来这篇博客学习子查询的第二种形式——列子查询 列子查询 子查询返回的结果是一列&#xff08;当然也可以是多行)&#xff0c;这种子查询称为列子查询。 列子查询可以使用的操作符 IN、NOT IN 、ANY&#xff08;any&#xff09;、SOME…

计算机组成结构—IO系统概述

目录 一、I/O 系统的发展 1. 早期阶段 2. 接口模块和 DMA 阶段 3. 通道结构阶段 4. 处理机阶段 二、I/O 系统的组成 1. I/O 软件 2. I/O 硬件 三、I/O 设备 1. I/O 设备分类 2. I/O 设备的组成 在计算机中&#xff0c;除 CPU 和主存两大模块之外&#xff0c;第三个重…

C#中使用Mysql批量新增数据 MySqlBulkCopy

在C#中使用MySqlBulkCopy类来批量复制数据到MySQL数据库&#xff0c;首先需要确保你的项目中已经引用了MySQL Connector。以下是使用MySqlBulkCopy的基本步骤&#xff1a; 1.安装MySQL Connector。 可以通过NuGet安装MySQL Connector&#xff1a; 2.在代码中引用必要的命名空间…

物资材料管理系统建设方案(Word)—实际项目方案

二、 项目概述 2.1 项目背景 2.2 现状分析 2.2.1 业务现状 2.2.2 系统现状 三、 总体需求 3.1 系统范围 3.2 系统功能 3.3 用户分析 3.4 假设与依赖关系 四、 功能需求 4.4.11.7 非功能性需求 五、 非功能性需求 5.1 用户界面需求 5.2 软硬件环境需求 5.3 产品质量需求 5.4 接口…

[线程与网络] Java虚拟机常考面试题(线程与网络完结)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;线程与…

使用 GPT-4 创作高考作文 2024年

使用 GPT-4 创作高考作文 2024年 使用 GPT-4 创作高考作文&#xff1a;技术博客指南 &#x1f914;✨摘要引言正文内容&#xff08;详细介绍&#xff09; &#x1f4da;&#x1f4a1;什么是 GPT-4&#xff1f;高考作文题目分析 ✍️&#x1f9d0;新课标I卷 人类智慧的进步&…

atomic特质的局限性

为什么在实际的 Objective-C 开发中, 几乎所有的属性都声明为 nonatomic ? 声明为 atomic 的属性我是真的没见过 在实际的 Objective-C 开发中&#xff0c;大多数属性通常声明为 nonatomic&#xff0c;主要原因包括性能考虑和常见的设计模式。具体原因如下&#xff1a; 性能问…

openai 前员工释放出关于AGI的前世今生和未来发展趋势的详细报告

目录 1.引言2.AGI的临近3.投资与工业动员4.国家安全与AI竞赛5.技术挑战与机遇6.项目与政策7.结语8.原文PDF链接PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源 1.引言 2024年&#xff0c;我们站在了一个全新的科技前沿。在这篇文…

【wiki知识库】06.文档管理页面的添加--前端Vue部分

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日目标 二、&#x1f43b;前端Vue模块的改造 BUG修改 1.wangeditor无法展示问题 2.弹窗无法正常关闭问题 2.1 添加admin-doc.vue 2.1.1 点击admin-ebook中的路由跳转到admin-doc 2.2.2 进入…

9.2 Go 接口的实现

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

在Ubuntu中进行PX4配置的过程中出现以下报错,且不能正常打开gazebo

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…