效果图如下:

elementui嵌套dialog内容不显示 el-table 嵌套_单选


在本文章中,我会讲一点代码的逻辑,仅供参考,因为代码是活的

话不多说我们开始!

首先是el-table嵌套el-table

这里要注意两个地方

1. 主table

1.1@select-all="mainSelectAll" -->主table的全选
        1.2@select="mainSelect" -->主table的单选
        1.3 :ref="main" -->主table的ref对象命名

2. 子table

2.1@select="subSelect" -->子单选
         2.2@select-all="subSelectAll" -->子全选 :ref="'sub' + scope.$index"

<el-table v-loading="loading" :data="personList" @selection-change="handleSelectionChange" ref="main"
      @select-all="mainSelectAll" @select="mainSelect">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column type="expand">
        <template slot-scope="scope">
          <el-table :data="scope.row.attachmentList" border stripe size="small" :show-header="false"
            :ref="'sub' + scope.$index" @select="subSelect" @select-all="subSelectAll">
            <el-table-column type="selection" width="100" align="center" />
            <el-table-column prop="attachmentName" label="证件名称" width="350" show-overflow-tooltip>
              <template slot-scope="props">
                <span style="color:red">证件名称:</span>{{ props.row.attachmentName }}
              </template>
            </el-table-column>
            <el-table-column prop="attachmentTypeName" label="证件类型" width="350" show-overflow-tooltip>
              <template slot-scope="props">
                <span style="color:red">证件类型:</span>{{ props.row.attachmentTypeName }}
              </template>
            </el-table-column>
            <el-table-column prop="validityDate" label="证件到期时间" width="350" show-overflow-tooltip>
              <template slot-scope="props">
                <span style="color:red">证件到期时间:</span>{{ props.row.validityDate }}
              </template>
            </el-table-column>
            <el-table-column prop="updateTime" label="最后更新时间" width="350" show-overflow-tooltip>
              <template slot-scope="props">
                <span style="color:red">最后更新时间:</span>{{ props.row.updateTime }}
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>
 </el-table>

下面开始讲解各方法!!

在讲解各方法前,需要先理解三个东西!

1. toggleRowExpansion(row, expanded);

elementui嵌套dialog内容不显示 el-table 嵌套_单选_02

 这个方法是展开表格,当我选中主table的时候,自动将子table展开

2. clearSelection();

elementui嵌套dialog内容不显示 el-table 嵌套_前端_03


 用于取消全选,清空选择

3.toggleRowSelection(row, selected);

elementui嵌套dialog内容不显示 el-table 嵌套_javascript_04

用于选中某条数据,row必须为单条数据(类似map形式),selected是否选中(true/false)

1. 主table的全选mainSelectAll方法

1. 取消全选时,循环main的数据拿到下标,将子table的所有全部选择都清空掉:clearSelection

2. 全选时将循环我personList(主表的数据),然后

        2.1:展开子table:toggleRowExpansion()方法

        2.2:如果selection有东西,执行主table选中/子table全选方法

        2.3:如果没有:执行cleanIs();清空方法

//主table全选
mainSelectAll(selection) {
  if (selection.length == 0) {
    var datas = this.$refs.main.data;
    datas.forEach((item, index) => {
      this.$refs[`sub${index}`].clearSelection()
    });
  } else {
    this.personList.forEach(async (item, index) => {
      await this.$refs['main'].toggleRowExpansion(item, true)
      if (selection.length !== 0) {
        let ls = new Array();
        ls.push(item);
        this.mainSelect(ls, item)
        this.subSelectAll(item.subList, index)
      } else {
        this.cleanIs(null, item)
      }
      this.$refs[`sub${index}`].clearSelection()
    });
  }
},


2. 主table的单选mainSelect方法

1. 参数讲解:

        1.1:selection->勾选过的数据

        1.2:row->当前点击勾选框的数据

2. 判断主table是否选中:isCheck

        2.1:查看selection是否存在row数据,如果没有就说明这条记录是取消

3. this.subIds

        subIds用于回显!!!!!!!!!!

//主table的单选
mainSelect(selection, row) {
  const isCheck = selection.includes(row);
  this.personList.forEach((item, index) => {
    if (item.id === row.id) {
      this.$refs.main.toggleRowExpansion(item, true);
      const tempList = row.attachmentList;
      this.$nextTick(() => {
        if (tempList.length !== 0) {
          tempList.forEach((childItem) => {
            this.selectAllChildMap.set(index, item);
            this.$refs.main.toggleRowSelection(item, isCheck);
            this.$refs[`sub${index}`].toggleRowSelection(childItem, isCheck);
            if (isCheck) {
              this.subIds.push(childItem.id);
            } else {
              this.subIds.pop(childItem.id);
            }
          })
        }
      })
    }
  })
  if (isCheck) {
    this.validIs(row.attachmentList);
  } else {
    this.cleanIs(null, row);
  }
},

3. 子table的全选subSelectAll()方法

1. 参数讲解

        1.1:selection -> 勾选过的数据

        1.2:clickIndex -> 下标(下标用于其他方法调用时,传进的参数)

//子表格勾选 --->联动一级表格
subSelectAll(selection, clickIndex) {
  if (selection != null && selection.length > 0) {
    const fatherRow = this.personList.find(item => {
      return item.id === selection[0].parentId
    })
    this.selectAllChildMap.set(clickIndex, fatherRow)
    this.$refs.main.toggleRowSelection(this.selectAllChildMap.get(clickIndex), true)
    // 非空时候 检验明细是否存在
    this.validIs(selection)
  } else {
    this.cleanIs(clickIndex, null);
    this.$refs.main.toggleRowSelection(this.selectAllChildMap.get(clickIndex), false)
    this.selectAllChildMap.delete(clickIndex)
  };
},

4. 子table的单选subSelect()方法

这里需要注意的是 我会循环selection 判断我本条数据是否存在,如果存在,flag为true;

1. 如果flag为true,则证明本条记录需要回显,会把id添加到全局变量的subIds里;

2. 如果flag为false,则需要把subIds里对应的记录删掉(本人不善于前端代码,所以用了最笨的方法就是循环重新赋值)

//子table单选
subSelect(selection, row) {
  const isCheck = selection.length > 0
  this.personList.forEach((item, index) => {
    if (item.id == row.tableId) {
      this.selectAllChildMap.set(index, item)
      this.$refs.main.toggleRowSelection(item, isCheck)
    }
  });
  let flag = false;
  selection.forEach((item, index) => {
    if (item.id == row.id) {
      //说明存在
      flag = true;
    }
  })

  if (flag) {
    this.subIds.push(row.id);
  } else {
    let ls = new Array();
    this.subIds.forEach(function(item, index, arr) {
      if (item == row.id) {

      } else {
        ls.push(item);
      }
    });
    this.subIds = ls;
  }
},


5. 其余代码(校验/清空/data里声明的参数 方面代码)

//data里需要声明的参数:
data() {
    return {
        selectAllChildMap: new Map(),
        ruleForm: {
            items: []
        },
}

---------------------------------------------------------------------------------
//一级勾选框和子级头部勾选框检验
validIs(selection) {
  // 非空时候 检验明细是否存在
  if (this.ruleForm.items.length === 0) {
    this.ruleForm.items.push(...selection)
  } else {

    let ids2 = this.ruleForm.items.map(f => f.id)
    selection.forEach(f => {
      if (ids2.indexOf(f.id) !== -1) {
        delete this.ruleForm.items[ids2.indexOf(f.id)]
      }
    })
    this.ruleForm.items = this.ruleForm.items.filter(f => f.id)
    ids2 = this.ruleForm.items.map(f => f.id)
    this.ruleForm.items.push(...selection)
  }
},

-----------------------------------------------------------------------------------------
//一级勾选框和子级头部勾选清空方法
cleanIs(clickIndex, fatherRow) {
  const childIdList = new Array();
  if (clickIndex != null && clickIndex >= 0) {
    childIdList.push(this.personList[clickIndex].attachmentList);
  } else {
    if (fatherRow != null && fatherRow != undefined) {
      childIdList.push(fatherRow.attachmentList);
    }
  }
  let ids2 = this.ruleForm.items.map(f => f.id)
  childIdList.forEach(f => {
    if (ids2.indexOf(f) !== -1) {
      delete this.ruleForm.items[ids2.indexOf(f)]
    }
  })
  this.ruleForm.items = this.ruleForm.items.filter(f => f.id)
  ids2 = this.ruleForm.items.map(f => f.id)
},


6. 数据结构

主table的personList就是这6条数据

每条数据内部有一个attachmentList:为我的子table的数据

elementui嵌套dialog内容不显示 el-table 嵌套_数据_05

7. 小结

1. 一定要理解最开始说的三个方法

        toggleRowExpansion

        clearSelection

        toggleRowSelection

2. 数据回显的subIds:一定是放在主/子table的单选方法里执行的,因为你全选时,会调用单选方法