vue+elementUI實現內嵌table的方法示例

在大四實習工作中碰到一個比較特別的需求,要求在一個 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內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: