弹窗里写表单,el-form表单里循环数组,最后进行表单验证

1.展示效果 

 

2.html代码

<el-form>里的 :model="registerForm" 绑定为一个对象, :rules="rules"要配合<el-form-item> 里的:prop一起使用进行表单验证,:prop要动态绑定数组的值,因此可以写为:prop="`processData.${index}.jurisdictionName`

<el-dialog :visible.sync="dialogRegister" width="1200px" :close-on-click-modal="false">
  <div>
    <div class="el-dialog-register-top">资产登记</div>
    <div style="padding: 10px" class="row-col-columns">
      <div class="row-col-columns-1">序号</div>
      <div class="row-col-columns-2">
        <span class="register-star">*</span>主机序列
      </div>
      <div class="row-col-columns-3">
        <span class="register-star">*</span>辖区
      </div>
      <div class="row-col-columns-2">
        <span class="register-star">*</span>型号
      </div>
      <div class="row-col-columns-2">
        <span class="register-star">*</span>资产名称
      </div>
      <div class="row-col-columns-3">
        <span class="register-star">*</span>所属厂家/品牌
      </div>
      <div class="row-col-columns-2">
        <span class="register-star">*</span>使用单位
      </div>
    </div>

    <el-form style="width: 100%;" size="medium" :model="registerForm" ref="ruleFormProp" :rules="rules">
      // 循环表单里的数组
      <div v-for="(item, index) in registerForm.processData" :key="index" class="row-col-columns">
        <div class="row-col-columns-1 number">{{ index + 1 }}</div>
        <div class="row-col-columns-2">
          <el-input v-model="item.alarmSerialNumber" disabled></el-input>
        </div>
        <div class="row-col-columns-3">
          <!-- 辖区 -->
          <el-form-item :prop="`processData.${index}.jurisdictionName`" :rules="rules.jurisdictionName">
            <el-input v-model="item.jurisdictionName" disabled></el-input>
          </el-form-item>
        </div>
        <div class="row-col-columns-2">
          <!-- 型号 -->
          <el-form-item :prop="`processData.${index}.model`" :rules="rules.model">
            <el-input v-model="item.model" disabled></el-input>
          </el-form-item>
        </div>
        <div class="row-col-columns-2">
          <el-form-item :prop="'processData.' + index + '.assetsName'" :rules="rules.assetsName">
            <el-input placeholder="请输入" class="addinput" v-model="item.assetsName">
            </el-input>
          </el-form-item>
        </div>
        <div class="row-col-columns-3">
          <el-form-item :prop="`processData.${index}.belongBrandId`" :rules="rules.belongBrandId">
            <el-cascader v-model.trim="item.belongBrandId" ref="cascaderList" @change="handleChange($event, index)"
              :props="{
                lazy: true,
                lazyLoad: lazyLoadAdd
              }">
            </el-cascader>
          </el-form-item>
        </div>
        <div class="row-col-columns-2">
          <!-- 使用单位 -->
          <el-form-item :prop="`processData.${index}.useId`" :rules="rules.useId">
            <el-select v-model="item.useId" clearable placeholder="使用单位" class="inputSelect">
              <el-option v-for="item2 in item.useOptions" :key="item2.value" :label="item2.label" :value="item2.value"></el-option>
            </el-select>
          </el-form-item>
        </div>
        <!--<div class="row-col-columns-1 number" @click="clearItem(item)">
          <svg class="iconfont" aria-hidden="true" style="width: 18px; height: 18px">
            <use xlink:href="#el-icon-myshanchu" />
          </svg>
        </div>-->
      </div>
    </el-form>
    <div class="footer-btn">
      <el-button @click="onCancel" class="btnSizeStyle">取 消</el-button>
      <el-button type="primary" @click="onSubmit" class="btnSizeStyle">确 定</el-button>
    </div>
  </div>
</el-dialog>

3.表单验证

表单里绑定的值写在data;表单验证必须使用validator,不然很可能验证不成功

data() {
  var checkassetsName = (rule, value, callback) => {
    if (!value) {
      return callback(new Error('请输入资产名称'));
     } else {
      callback();
    }
  };
  var checkbelongBrandId = (rule, value, callback) => {
    if (value.length === 0) {
      return callback(new Error('请选择所属厂家'));
    } else if (value[0] === 'ditto' && value[1] === 0) {
      return callback(new Error('第一条数据不能为同上'));
    } else if (value.length === 2 && value[0] !== 'ditto') {
      return callback(new Error('请选择品牌'));
    } else {
      callback();
    }
  };
  var checkuseId = (rule, value, callback) => {
    if (!value) {
      return callback(new Error('请选择使用单位'));
    } else {
      callback();
    }
  };
  return {
    dialogRegister: false, // 批量资产登记弹窗
    registerLoading: false,
    registerForm: { // 表单
      processData: [] // 用于接收后端数组
    },
    rules: {
      assetsName: [{ validator: checkassetsName, trigger: 'blur' }],
      belongBrandId: [{ validator: checkbelongBrandId, trigger: 'change' }],
      useId: [{ validator: checkuseId, trigger: 'change' }],
    }
  }
}

4. 获取使用单位

获取使用单位,使用resolve将异步操作成功的数据传参给第7步

// 使用单位
getUse() {
  return new Promise((resolve, reject) => {
    organizationApiManagement('GET', '', 'find').then(res => {
      const arr = [] // 全部
      if (res.code !== '0000') {
        resolve(arr)
      } else {
        res.data.list.forEach(item => {
          const k = {
            serialNo: item.serialNo,
            value: item.id,
            label: item.organizationName
          }
          arr.push(k)
          resolve(arr)
        })
      }
    })
  })
},
// 使用单位数据结构为
// [
//   {label: "华为",serialNo: "1519863055532449792",value: 42},
//   {label: "浙江大华技术股份有限公司",serialNo: "1460855692123456896",value: 2}
// ]

5.根据厂家选择品牌

项目需要根据厂家选择品牌,因此使用联级选择器,看不懂得可以注释相关代码

import { belongBrand } from '@/utils/manufacturerBrand' // 为js文件

// 获取厂家及品牌
async lazyLoadAdd(node, resolve) {
  console.log(node)
  if (node.level === 0) {
    return resolve(await belongBrand(node.level + 1))
  } else if (node.level === 1) {
    return resolve(await belongBrand(node.level + 1, node.value))
  }
},

// 即选择厂家也选择品牌,才能给数组push下标,进行rules验证
handleChange(e, index) {
  e.push(index)
},

6. manufacturerBrand.js文件


import { organizationApiManagement } from '@/api/property/pointInterface'
import { getBrandApi } from '@/api/property/assets'

const belongBrand = async (level, id) => {
  return new Promise((resolve) => {
    console.log(level)
    if (level === 1) {
      const organizationArr = []
      // 获取所属厂家
      organizationApiManagement('GET', '', 'findList').then(res => {
        if (res.code === '0000') {
          res.data.forEach((item) => {
            const k = {
              value: item.id,
              label: item.organizationName,
              children: []
            }
            organizationArr.push(k)
          })
          // 同上数据不加children代表下一级没值了
          const ditto = {value: "ditto" , label: '同上'}
          organizationArr.push(ditto)
          resolve(organizationArr)
        } else {
          resolve(organizationArr)
        }
      })
    } else if (level === 2) {
        const arr = []
        const params = {
          factoryId: id
        }
        // 获取品牌
        getBrandApi(params).then(res => {
          if (res.code === '0000') {
            res.data.forEach(item => {
              const k = {
                value: item.id,
                label: item.typeName,
                children: [],
                leaf: true // 这个代表联级选择到此结束
              }
              arr.push(k)
            })
            resolve(arr)
          } else {
            resolve(arr)
          }
        })
      // }
    }
  })
}
export { belongBrand }

// 所属厂家数据结构
// [
//   {children: [], label: "华为", value: 42},
//   {children: [], label: "浙江宇视科技有限公司", value: 15},
//   {label: "同上",value: "ditto"}
// ]

// 选择华为获得的品牌
// [
//   {children: [], label: "华为",leaf: true, value: 12}
// ]

7. 或取表单数组,赋值渲染页面

获取后台数组,本来后端这部没写接口,但是不写接口我的inpurt和select都选择不了,我以为要写异步,我将选中行列表的数据放到promis里面使用,但还是不行,所有又麻烦后端写接口

// 批量资产登记
async assetsRegister() {
  this.registerLoading = true
  // 因为除了第一个都要有同上选项,因此放在了这里
  const useOptions = await this.getUse() // 使用单位列表
  // 根据主机序列号获取详情信息
  const host = ['188720045', '450022554']
  // this.selectList为选中行的数据,因为你们没有,我写默认值
  //this.selectList.forEach(item => {
  //  host.push(item.alarmSerialNumber)
  //})
  const params = { alarmSerialNumber: host }
  alarmRecordApiManagement('GET', 'findDetail', params).then(res => {
    switch (res.code) {
      case '0000':
        res.data.forEach((item, index) => {
          item.assetsName = '' // 资产名称
          item.jurisdictionCode = '43010413' // 银盆岭编码,传给后台
          item.jurisdictionName = '湖南省长沙市岳麓区银盆岭街道' // 前端显示
          item.model = '其他'
          item.belongBrandId = [] // 同时绑定所属厂家(数组第一个值)和品牌(第二个值)绑定的值
          item.useId = '' // 使用单位
          item.useOptions = useOptions // 使用单位下拉数组
          
          const dittoVal = [{ value: "ditto", label: '同上' }]
          if (index !== 0) { // 不是第一条,都同上
            item.useId = 'ditto'
            // 此方法不改变原数组添加数据,从第二条开始数据包含同上
            item.useOptions = item.useOptions.concat(dittoVal)
          }
        })
        this.registerForm.processData = res.data
        this.dialogRegister = true
        this.registerLoading = false
        break
      default:
        this.$message.error(res.message)
        this.registerLoading = false
        break
    }
  })
},

// 因为不写接口,前端会有问题,所有这个接口里面没什么值,有用的只有
//[
//  {alarmSerialNumber:"188720045"},
//  {alarmSerialNumber:"450022554"}
//]

8. 取消和确定事件

// 取消
onCancel() {
  this.registerForm.processData = []
  this.dialogRegister = false
},

// 确定
onSubmit() {
  this.$refs.ruleFormProp.validate((valid) => {
    if (valid) {
      console.log('执行操作')
    }
  })
}

9. css样式

.el-dialog-register-top {
  margin-top: -30px;
  padding: 10px;
  font-size: 18px;
  color: #333;
  border-bottom: 1px solid #E4E7ED;
}

.row-col-columns {
  color: #333;
  display: flex;
  margin-left: 8px;
  div {
    padding-right: 5px;
  }
  ::v-deep .el-input.is-disabled .el-input__inner {
    color: #333;
  }
  .number {
    padding: 10px 0 0 15px;
  }
  .row-col-columns-1 {
    width: 40px;
  }
  .row-col-columns-2 {
    width: 180px;
  }
  .row-col-columns-3 {
    width: 240px;
  }
  .register-star {
    color: #F56C6C;
  }
}

10. 每个接口后端返回的值我都写在后面了,你们可以进行替换,相关注释也写在代码中

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值