Vue+Element-ui实例_在form中动态校验tag标签

1.开发需求

在日常开发中,我们会遇到form表单的动态添加和校验,当我们需要在动态添加的内容中再次动态使用输入框的时候,就会变得很繁琐,我在网上找了很多案例,没有符合自己需求的内容,只好闲暇时间自己搞一下了...

比如一下操作,在一个输入框中输入多个批号,然后提示多个批号有逗号分开。这种操作让用户操作起来就很不方便
然后我就想到了,在element中,有一个动态添加tag的案例,于是就想着使用这个方式去动态添加多种批号,但是,但是**,**这个是放在动态表单中的,最主要的是要校验这个批号是否填写,所以,这个需求就有了很大的挑战性

2.实现演示

下面是我完成后的演示,请看

上述操作不仅仅实现了动态添加tag操作,也实现了动态校验每一个批号是否填写的功能(牛批)

3.主要难点解析

3.1动态添加form表单

其实这个对于一个前端来说没什么难点,这个在element中也有案例

3.2动态校验动态添加的tag标签

说到底,这个才是本文主要介绍的难点,因为tag的动态添加是循环一个数组,input只是为这个数组添加内容,但是你要在form表单中校验一个数组,你会使用什么组件呢,没错,就是多选框,请看代码

我使用一个空的多选项,而且这个东西还不能给用户看到,v-show="false"隐藏掉,这样就能去"校验"tag标签了(机智如我)

3.3动态的添加、删除tag标签

其实这个在element中有案例,我单独拿出来说一下,肯定是有要提醒的地方,那就是在点击"添加批号"按钮的时候,按钮会"变成"输入框,如果只有一个tag标签数组就没有问题,和官网案例一样,但是要是多个tag标签数组就会报错,所有我们要动态添加一个**"ref"** ,请看代码

在点击"添加批号"的按钮是,动态的去显示input输入框,并且使 input 获取焦点

好啦难点也都讲完了,该给大家提供福利了,贴代码

点个赞呗~

html 复制代码
<template>
  <div id="app">
    <div class="app-container">
      <el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="100px" class="demo-dynamic">
        <el-form-item prop="email" label="批号" :rules="[
            { required: true, message: '请输入批号地址', trigger: 'blur' },
          ]">
          <el-input placeholder="请输入批号(多种批号请用英文逗号分割)" v-model="dynamicValidateForm.email"></el-input>
        </el-form-item>
        <el-form-item v-for="(domain, index) in dynamicValidateForm.domains" :label="'批号' + index" :key="domain.key"
          :prop="'domains.' + index + '.value'" :rules="{
            required: true,
            message: '批号不能为空',
            trigger: 'blur',
          }">
          <el-checkbox-group v-show="false" v-model="domain.value">
          </el-checkbox-group>
          <el-tag :key="tag" v-for="tag in domain.value" closable :disable-transitions="false"
            @close="handleClose(tag, domain ,index)">
            {{tag}}
          </el-tag>
          <el-input class="input-new-tag" v-if="domain.inputVisible" v-model="domain.inputValue" :ref="domain.refs"
            size="small" @keyup.enter.native="handleInputConfirm(domain,index)"
            @blur="handleInputConfirm(domain,index)">
          </el-input>
          <el-button v-else class="button-new-tag" size="small" icon="el-icon-plus"
            @click="showInput(domain,index,domain.refs)">添加批号
          </el-button>
          <el-button @click.prevent="removeDomain(domain)">删除</el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('dynamicValidateForm')">提交</el-button>
          <el-button @click="addDomain">新增批号</el-button>
          <el-button @click="resetForm('dynamicValidateForm')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        dynamicValidateForm: {
          domains: [{
            value: [],
            inputVisible: false,
            inputValue: "",
            refs: 'domRefs0'
          }],
          email: "",
        },
        inputVisible: false,
        inputValue: ''
      };
    },
    mounted() {},
    methods: {
      // 数组是不是有重复
      hasDuplicates(array) {
        return array.length !== new Set(array).size;
      },
      hasIncloud(array, value) {
        return array.indexOf(value) !== -1;
      },
      handleClose(tag, domain, index) {
        this.dynamicValidateForm.domains[index].value.splice(this.dynamicValidateForm.domains[index].value.indexOf(tag),
          1);
      },
      showInput(domain, index, refs) {
        this.dynamicValidateForm.domains[index].inputVisible = true;
        this.$nextTick(() => {
          this.$refs[refs][0].$refs.input.focus();
        });
      },

      handleInputConfirm(domain, index) {
        let inputValue = domain.inputValue;
        let valArray = this.dynamicValidateForm.domains[index].value
        let isSet = this.hasIncloud(valArray, inputValue);
        if (!isSet) {
          if (inputValue) {
            this.dynamicValidateForm.domains[index].value.push(inputValue);
          }
        } else {
          this.$message({
            message: "批号不能重复填写!",
            type: "warning",
          });
        }
        this.dynamicValidateForm.domains[index].inputVisible = false;
        this.dynamicValidateForm.domains[index].inputValue = '';
      },
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            console.log("this.dynamicValidateForm:", this.dynamicValidateForm)
            alert("submit!");
          } else {
            console.log("error submit!!");
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      },
      removeDomain(item) {
        var index = this.dynamicValidateForm.domains.indexOf(item);
        if (index !== -1) {
          this.dynamicValidateForm.domains.splice(index, 1);
        }
      },
      addDomain() {
        let len = this.dynamicValidateForm.domains.length
        this.dynamicValidateForm.domains.push({
          value: [],
          inputVisible: false,
          inputValue: "",
          refs: "domRefs" + len,
          key: Date.now(),
        });
      },
    },
  };
</script>

<style>
  .el-tag+.el-tag {
    margin-left: 10px;
  }

  .button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
  }

  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }
</style>
相关推荐
wen's20 分钟前
React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
javascript·react native·react.js
vvilkim1 小时前
Electron 自动更新机制详解:实现无缝应用升级
前端·javascript·electron
vvilkim1 小时前
Electron 应用中的内容安全策略 (CSP) 全面指南
前端·javascript·electron
aha-凯心1 小时前
vben 之 axios 封装
前端·javascript·学习
漫谈网络1 小时前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
失落的多巴胺3 小时前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear3 小时前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息3 小时前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月3 小时前
1.vue权衡的艺术
前端·vue.js·开源
RunsenLIu3 小时前
基于Vue.js + Node.js + MySQL实现的图书销售管理系统
vue.js·mysql·node.js