Bootstrap

form表单内嵌套动态表格添加校验功能

懒……
使用element ui的表单加表格功能开发时,遇到动态表单的验证问题,
解决方式如下

<template>
  <div class="box">
    <div class="tabletitle">
      <span v-text="title" />
    </div>
    <el-form ref="formRef" :model="form" :rules="rules">
      <el-table
        ref="table"
        border
        :data="form.dataList"
        stripe
        fit
        highlight-current-row
        style="width: 100%"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column align="center" label="姓名" prop="managementName" min-width="200" show-overflow-tooltip>
          <template slot-scope="{row, $index}">
            <el-form-item v-if="row.isEdit" :prop="'dataList.' + $index + '.managementName'" :rules="rules.managementName">
              <el-input v-model="row.managementName" size="mini" />
            </el-form-item>
            <span v-if="!row.isEdit">{{ row.managementName }}</span>
          </template>
        </el-table-column>
        <el-table-column align="center" label="联系方式" prop="managementPhone" min-width="200" show-overflow-tooltip>
          <template slot-scope="{row, $index}">
            <el-form-item v-if="row.isEdit" :prop="'dataList.' + $index + '.managementPhone'" :rules="rules.managementPhone">
              <el-input v-model="row.managementPhone" size="mini" />
            </el-form-item>
            <span v-else>{{ row.managementPhone }}</span>
          </template>
        </el-table-column>
        <el-table-column align="center" label="邮箱" prop="managementEmail" min-width="200" show-overflow-tooltip>
          <template slot-scope="{row}">
            <el-form-item v-if="row.isEdit">
              <el-input v-model="row.managementEmail" size="mini" />
            </el-form-item>
            <span v-else>{{ row.managementEmail }}</span>
          </template>
        </el-table-column>
        <el-table-column align="center" label="操作" min-width="200" show-overflow-tooltip>
          <template slot-scope="{row,$index}">
            <el-button v-if="!row.isEdit" type="text" @click="handleEdit(row)">编辑</el-button>
            <el-button v-else type="text" @click="handleSave(row,$index,['managementName','managementPhone'])">保存</el-button>
            <!-- <icon-button v-if="!row.isEdit" v-editLine icon="edit" />
            <icon-button v-if="row.isEdit" v-checkSubmit icon="check" title="保存" @submit="handleSuccessClick(row)" /> -->
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <div class="bts">
      <el-button type="primary" size="mini" @click="addUserInfo">添加明细</el-button>
      <el-button type="primary" size="mini" @click="deleteUserInfo">删 除</el-button>
    </div>
  </div>
</template>

<script>
import { cloneDeep } from 'lodash'

export default {
  name: 'ClientLinkmanInfo',
  props: {
    title: {
      type: String,
      default: '客户联系人信息'
    },
    tableData: {
      type: Array,
      default: () => ([])
    }
  },
  data() {
    return {
      form: {
        dataList: [
          // {
          //   managementName: 'zj',
          //   managementPhone: '113313131',
          //   managementEmail: '[email protected]',
          //   managementType: '2', // 管理信息类型;1:运营人员信息,2:客户联系人信息
          //   isEdit: false
          // }
        ]
      },
      // 表单验证规则
      rules: {
        managementName: [{ required: true, message: '请输入姓名!', trigger: 'blur' }],
        managementPhone: [{ required: true, message: '请输入联系方式!', trigger: 'blur' }]
      },
      tableSeletList: []
    }
  },
  watch: {
    'tableData': function(newValue, oldValue) {
      const data = cloneDeep(newValue).map(item => {
        item.isEdit = false
        return item
      })
      this.form.dataList = data
    }
  },
  mounted() {
    // const _data = this.tableData
    // this.dataList = _data.map(item => {
    //   item.isEdit = false
    //   return item
    // })
  },
  methods: {
    handleSelectionChange(val) {
      this.tableSeletList = val
    },
    addUserInfo() {
      const row = {
        managementName: '',
        managementPhone: '',
        managementEmail: '',
        managementType: '2', // 管理信息类型;1:运营人员信息,2:客户联系人信息
        isEdit: true
      }
      this.form.dataList.push(row)
    },
    deleteUserInfo() {
      if (!this.tableSeletList.length) {
        this.$message('请选择要删除的数据')
      }
      this.tableSeletList.forEach((item, i) => {
        console.log(item)
        if (this.form.dataList.indexOf(item) != -1) {
          this.form.dataList.splice(this.form.dataList.indexOf(item), 1)
        }
      })
    },
    // 校验
    validateField(form, index, validateArr) {
      let result = true
      const propsArr = validateArr.map(item => `dataList.${index}.${item}`)
      this.$refs[form].validateField(propsArr, err => {
        if (err != '') {
          result = false
        }
      })
      return result
    },
    handleEdit(row) {
      row.isEdit = true
    },
    handleSave(row, index, validateArr) {
      if (!this.validateField('formRef', index, validateArr)) return
      row.isEdit = false
    },
    validate() {
      return this.$refs.formRef.validate()
    },
    validateCheck() {
      const item = this.form.dataList.find(item => item.isEdit)
      return item || !this.form.dataList.length
    }
  }
}
</script>

<style scoped>
  .box {
    padding: 0 20px 10px;
  }
  .tabletitle {
    margin-bottom: 10px;
  }
  .bts {
    text-align: right;
    margin-top: 10px;
  }
</style>

;