vue elementui 动态追加下拉框、输入框

vue elementui 动态追加下拉框、输入框

上代码:

html 复制代码
<template>
  <div>
    <el-dialog
      append-to-body
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      width="65%"
      @close="onClose"
      :modal-append-to-body="true"
      title="新建"
      custom-class="dialogBox"
      :visible.sync="dialogVisible"
      :lock-scroll="true"
      :destroy-on-close="true">
      <el-form :model="combinationInfo" label-width="90px" ref="combinationForm" :rules="rules" :inline="true" size="small">
        <el-row>
          <el-col :span="12">
            <el-form-item prop="benchMarks" label="名称">
              <div style="color: #fb6b3f;width: 230px;">比例之和需为100%(当前
                <span>{{benchmarkTotal}}</span>
                <span></span>%)
              </div>
              <div v-for="(item,index) in combinationInfo.benchMarks" :key="index">
                <el-select
                  style="margin-bottom: 10px;"
                  clearable
                  filterable
                  collapse-tags
                  placeholder="请选择"
                  class="benchmarkSelectWidth"
                  @change="changeBenchmark"
                  v-model="item.code"
                >
                  <el-option
                    v-for="(item1, idx) in list"
                    :key="idx"
                    :label="item1.name"
                    :value="item1.code"
                  >
                  </el-option>
                </el-select>
                <el-input v-model="item.percentage" @input="changePercentage" placeholder="请输入" class="benchmarkInputWidth"></el-input>
                <span style="padding-left: 2px;">%</span>
                <i v-if="index !== 0" style="font-size: 18px;cursor: pointer;padding: 0 0 0 10px;color: #F56C6C;" @click="deleteIndex(index)" class="el-icon-remove-outline"></i>
              </div>
              <div v-if="benchmarkRule" style="color: #F56C6C;font-size: 12px;margin-top: -17px">请选择名称</div>
              <el-button @click="addIndex" size="mini" type="primary" icon="el-icon-plus">添加</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          </el-col>
        </el-row>
      </el-form>
      <div style="text-align: right;margin-top: 20px;">
        <el-button size="mini" @click="onClose()">取 消</el-button>
        <el-button
          size="mini"
          type="primary"
          @click="onConfirm()"
          >提 交</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>
javascript 复制代码
data() {
    return {
      dialogVisible: false,
      combinationInfo: {
        benchMarks: [
          {
            code: '',
            name: '',
            percentage: '',
          }
        ]
      },
      rules: {
        benchMarks: [{ required: true }],
      },
      benchmarkRule: false,
      benchmarkTotal: 0,
      list: [
        {
          name: 'aaa',
          code: '111',
        },
        {
          name: 'bbb',
          code: '222',
        },
        {
          name: 'ccc',
          code: '333',
        },
      ],
    }
  },

methods: {
 // 添加
    addIndex () {
      this.combinationInfo.benchMarks.push({
        code: '',
        percentage: '',
      })
    },
    // 删除
    deleteIndex (index) {
      this.combinationInfo.benchMarks.splice(index,1)
      this.changePercentage()
    },
    changeBenchmark (val) {
      if (this.combinationInfo.benchMarks.length && this.combinationInfo.benchMarks.length > 1) {
        if (!this.isRepeat(this.combinationInfo.benchMarks,'code')) {
          this.$message.warning('所选名称不能重复!')
          return
        }
      }
    },
     // 判断数组中是否有重复数据(true 不存在;false 存在重复)
    isRepeat(arr, key) {
      var obj = {};
      for (let i = 0; i < arr.length; i ++) {
          if (obj[arr[i][key]]) {
              return false;    // 存在
          } else {
            obj[arr[i][key]] = arr[i];
          }
      }
      return true;
    },
    // 名称值变化时
    changePercentage (val) {
      this.benchmarkTotal = 0
      if (this.combinationInfo.benchMarks.length && this.combinationInfo.benchMarks.length > 0) {
        for(let i = 0; i < this.combinationInfo.benchMarks.length; i++) {
          if (this.combinationInfo.benchMarks[i].percentage === '') {
            break
          }
          this.benchmarkTotal+=parseFloat(this.combinationInfo.benchMarks[i].percentage)
        }
      }
    },
    // 提交
    onConfirm() {
      if (this.combinationInfo.benchMarks) {
          for(let i = 0; i< this.combinationInfo.benchMarks.length; i++) {
            if (this.combinationInfo.benchMarks[i].code) {
              this.benchmarkRule = false
            } else {
              this.benchmarkRule = true
              return
            }
          }
        }
        if (this.benchmarkTotal !== 100) {
          this.$message.warning('名称比例之和需为100%!')
          return
         }
     },
     // 取消
    onClose() {
      this.benchmarkRule = false
      this.dialogVisible = false
    },
},

展示效果图:

相关推荐
Lank_M几秒前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写2 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李4 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易18 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马29 分钟前
前沿视界
前端
kyriewen34 分钟前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒1 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端
Flynt2 小时前
别写拖拽行为,只声明"能拖到哪":UIST 最佳论文的拖拽方案我实测了
前端·svg·preact
Moment3 小时前
代码都能让 Agent 写了,我们为什么还要学前端?
前端·后端·面试