前言

最近在写项目的时候,有个使用el-table内嵌动态table的功能需求,也就是table内嵌table,同时里面的table数据是动态获取的,动态获取动态展开

问题

按照element的table里面的方法,行属性设置了type='expand',也在table里面添加了@expand-change="expandChange"时间监听展开行事件,在监听时间里面动态获取数据赋值给里面展开的table,
问题出现了,第一次点开没数据,第二次点开才有数据
①:第一次点开效果

②:第二次展开数据显示出来

解决

看到这个其实都知道是dom数据渲染不同步造成的(没有及时回显),那么该怎么做呢?于是开始了自我尝试以及度娘的过程,过程中发现了很多小伙伴也遇到了这样的问题,也有很多方法:
1:使用this.$nextTick的,
2:使用v-if显示隐藏内嵌table的,
3::有不使用@expand-change方法---改成toggleRowExpansion控制的,
但是最终这些方法或多或少都有问题,当时自己也是一脸懵逼不知道咋办,

     中午休息的时候突然灵光一闪,既然是dom渲染的问题,为何我不先给这行数据里面加上一个我需要的数据,动态获取的数据直接丢进去,这样是不是就解决了呢?说干就干:     **第一步**:原来的设置不变,稍微改动一下展开行
<el-table      class="common-table"      :data="tableData"      style="width: 100%"      stripe      border      @expand-change="expandChange"    >      <el-table-column type="expand">        <template slot-scope="scope">          <el-table :data="scope.row.ruleItemData" border stripe style="width: 100%">            <el-table-column prop="questioncount" label="试题数量"></el-table-column>          </el-table>        </template>      </el-table-column>      <el-table-column prop="regionName" label="地区"></el-table-column>    </el-table>

第二步:获取外部table表数据的时候强制追加一个数据项

// 获取表数据    queryData() {      rule.selectByPage(this.queryForm).then(res => {        if (res) {          //给每行数据强制追加一个数据项          res.content.list.map(item => {            item.ruleItemData = [];          });          this.tableData = res.content.list;        }      });    },

第三步:动态获取内嵌表数据,动态赋值当前行

// 展开事件----动态获取内嵌表数据    expandChange(row, expandedRows) {      // 该处是用于判断是展开还是收起行,只有展开的时候做请求,避免多次请求!      // 展开的时候expandedRows有值,收起的时候为空.      if (expandedRows.length > 0) {        rule          .itemSelectByRuleID({            examruleid: row.id          })          .then(res => {            // 遍历当前页面表            this.tableData.forEach((temp, index) => {              // 找到当前点击的行,把动态获取到的数据赋值进去              if (temp.id === row.id) {                this.tableData[index].ruleItemData = res.content;              }            });          });      }    }

这样就完美了,不论点开哪一行都是动态渲染哪一行的内嵌表数据。

附上精简了一下的整体代码供大家参考

<template>  <div class="common-page">    <el-table      class="common-table"      :data="tableData"      style="width: 100%"      stripe      border      @expand-change="expandChange"    >      <el-table-column type="expand">        <template slot-scope="scope">          <el-table :data="scope.row.ruleItemData" border stripe style="width: 100%">            <el-table-column prop="questioncount" label="试题数量"></el-table-column>          </el-table>        </template>      </el-table-column>      <el-table-column prop="regionName" label="地区"></el-table-column>    </el-table>  </div></template><script>import { rule } from "@/api/api";export default {  data() {    return {      queryForm: {},      tableData: []    };  },  created() {    this.queryData();  },  methods: {    // 获取表数据    queryData() {      rule.selectByPage(this.queryForm).then(res => {        if (res) {          //给每行数据强制追加一个数据项          res.content.list.map(item => {            item.ruleItemData = [];          });          this.tableData = res.content.list;        }      });    },    // 展开事件----动态获取内嵌表数据    expandChange(row, expandedRows) {      // 该处是用于判断是展开还是收起行,只有展开的时候做请求,避免多次请求!      // 展开的时候expandedRows有值,收起的时候为空.      if (expandedRows.length > 0) {        rule          .itemSelectByRuleID({            examruleid: row.id          })          .then(res => {            // 遍历当前页面表            this.tableData.forEach((temp, index) => {              // 找到当前点击的行,把动态获取到的数据赋值进去              if (temp.id === row.id) {                this.tableData[index].ruleItemData = res.content;              }            });          });      }    }  }};</script><style></style>

希望对遇到相同问题的小伙伴有帮助,收工!