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>
相关推荐
GIS程序媛—椰子11 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
ZL不懂前端20 分钟前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x24 分钟前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt
麦麦大数据1 小时前
基于vue+neo4j 的中药方剂知识图谱可视化系统
vue.js·知识图谱·neo4j
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
理想不理想v2 小时前
vue经典前端面试题
前端·javascript·vue.js