在大四实习工作中碰到一个比较特别的需求,要求在一个 table 表格中点击一条数据的编号,在该条数据下方出现一个新的 table 表格。这个需求在 element ui 的官方文档中也有案例,以下是参考了其他博客(找不到博客地址了)和 element ui 之后的最终实现效果。

效果图

不知道是公司电脑比较拉,还是软件问题导致录制出来的动态图很卡,但是在实际操作并不会卡。

代码:

页面显示代码:

主要代码在于 <el-table-column type="expand" width="1" >
type="expand" 官方解释:
通过设置 type="expand" 和 scoped slot 可以开启展开行功能,el-table-column 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 scoped slot 相同。
而最后通过 width="1"el-table-column 设置为 type="expand"之后自带显示的 箭头 图标隐藏。

整个代码流程大致如下:
数据表分为 主表和子表,页面最开始加载时展示主表 table 数据(也就是普通的 table 数据表格,就叫它主 table )。当我点击主 table 中的一行数据的导航名称时,触发一个点击事件 toogleexpand() 。这个事件的主要功能是根据点击数据的 id 去后台查找与其对应的子表数据返回到前端,最后前端在进行展示。
这过程比较值得注意的是,拿到对应数据的子表数据之后,怎么与主表数据一一绑定。
这里我是通过使用 map 的方式实现的,通过以主表 id 为 key ,子表数据为 value .

// 使用 map 结构的方式保存翻译列表
this.websitelangmap.set(id,response.rows)

到了这一步还存在一个问题。
在页面刚加载的时候第一次点击打开对应的内嵌 table 是没有数据的,只有第二次点击打开才会有数据。
因为是 table 第一次渲染的时候 我们保存的子表数据的 map 是没有数据的,所以第一次点击并不会显示数据(没有数据怎么渲染)。而我们获取数据是在点击事件 toogleexpand() 触发之后会请求到的数据。也就是先渲染后才有数据。原先我以为它能像监听器一样,能实时监听 data 的变化而渲染页面,然而并不能。
解决办法是:控制 el-table 的 key 属性,在子表数据发生变化是改变的 key 的值。

this.websitelangtablekey = !this.websitelangtablekey;

以下是核心代码:

<el-table 
      v-loading="loading" 
      :data="websitelist" 
      @selection-change="handleselectionchange"
      ref="table"
      key="websitetable"
      row-key="id"
      style="width: 100%; maigin-bottom: 20px;"
      border
    >
      <el-table-column type="selection" width="55" align="center" />
      <!-- <el-table-column :label="td('主键')" align="center" prop="id" /> -->
      <el-table-column :label="td('上级导航')" align="center" prop="parentid" />
      <el-table-column :label="td('导航名称')" align="center" prop="barname" >
        <template slot-scope="scope" >
          <el-link type="primary" :underline="false" @click="toogleexpand(scope.row)" >
            {{scope.row.barname}}
          </el-link>
        </template>
      </el-table-column>
      <el-table-column :label="td('是否链接')" align="center" prop="islink" />
      <el-table-column :label="td('链接地址')" align="center" prop="url" />
      <el-table-column :label="td('创建日期')" align="center" prop="createtime" />
      <el-table-column :label="td('创建用户')" align="center" prop="createby" />
      <el-table-column :label="td('更新时间')" align="center" prop="updatetime" />
      <el-table-column :label="td('更新用户')" align="center" prop="updateby" />
      <el-table-column :label="td('备注')" align="center" prop="remark" />
      <el-table-column :label="td('操作')" align="center" width="130" class-name="small-padding fixed-width" fixed="right">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleupdate(scope.row)"
            v-haspermi="['cms:website:edit']"
          >{{td("修改")}} </el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handledelete(scope.row)"
            v-haspermi="['cms:website:remove']"
          >{{td("删除")}}</el-button>
        </template>
      </el-table-column>

      <el-table-column type="expand" width="1" >
        <template slot-scope="scope">
          <el-table 
            v-loading="loading" 
            style="width: 100%"
            row-key="langid"
            :key="websitelangtablekey"
            :data="websitelangmap.get(scope.row.id)"
            class="table-in-table"
          >
            <!-- <el-table-column :label="td('id主键')" align="center" prop="langid" /> -->
            <!-- <el-table-column :label="td('导航id')" align="center" prop="webid" /> -->
            <el-table-column :label="td('语言编号')" align="center" prop="langcode" />
            <el-table-column :label="td('语言名称')" align="center" prop="langname" />
            <el-table-column :label="td('中文')" align="center" prop="langcn" />
            <el-table-column :label="td('语言翻译')" align="center" prop="langtranslate" />
            <el-table-column :label="td('备注')" align="center" prop="remark" />
            <el-table-column :label="td('操作')" align="center" width="130" class-name="small-padding fixed-width" fixed="right">
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-edit"
                  @click="handleupdatelang(scope.row)"
                  v-haspermi="['cms:websitelang:edit']"
                >{{td("修改")}} </el-button>
                <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-delete"
                  @click="handledeletelang(scope.row)"
                  v-haspermi="['cms:websitelang:remove']"
                >{{td("删除")}}</el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>
    </el-table>
	// 内嵌 table 
    toogleexpand(row) {
      this.getlistlang(row.id);
      let $table = this.$refs.table;
      $table.togglerowexpansion(row)
    },
     /** 查询导航翻译列表 */
    getlistlang(id) {
       // 根据 导航id 获取翻译列表
      this.langqueryparams.webid = id;
      listwebsitelang(this.langqueryparams).then(response => {
        // 使用 map 结构的方式保存翻译列表  
        this.websitelangmap.set(id,response.rows)
        this.websitelangtablekey = !this.websitelangtablekey;
        this.resetlang();
      });
    },
<style lang="scss" scoped>
.app-container {
  ::v-deep {
    .el-table th {
      background: #ddeeff;
    }
    .el-table__expanded-cell {
      border-bottom: 0px;
      border-right: 0px;
      padding: 0px 0px 0px 47px;
    }
  }
  .table-in-table {
    border-top: 0px;
  }
}
</style>

到此这篇关于vue+elementui实现内嵌table的方法示例的文章就介绍到这了,更多相关vue element内嵌table内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!