Utilice ElementPlus para implementar tablas en línea y paginación en línea

Prefacio

A veces nos encontramos con un requisito de este tipo, que es incrustar una tabla dentro de la tabla y requerir paginación, lo cual es fácil de implementar en ElementPlus. A continuación se utiliza la sintaxis de Vue2 para implementar un ejemplo simple. Después de todo, Vue3 es compatible con la sintaxis de Vue2. Si desea un ejemplo de la versión de Vue3, simplemente cámbielo y estará bien.

1. Código de muestra

(1)/src/views/Example/InlineTable/index.vue

<template>
  <div class="index" v-loading="elementLoading" element-loading-text="数据正在加载中...">

    <!-- 外层表格 -->
    <div class="outer-table-container">
      <el-table
        border
        size="small"
        row-key="id"
        ref="outerTableRef"
        height="100%"
        highlight-current-row
        :data="outerData.list"
        :expand-row-keys="outerData.expandedKeys"
        @expand-change="handleOuterDataExpandChange"
      >

        <el-table-column fixed prop="id" label="游戏服务器ID" width="200" align="center">
          <template #default="scope">
            <p>{
   
   { scope.row.id }}</p>
          </template>
        </el-table-column>

        <el-table-column fixed prop="id" label="玩家列表" type="expand" width="200" align="center">
          <template #default="scope">
            <div class="outer-table-container-td__playerList" v-loading="scope.row.loading">
              <!-- ^ 内嵌表格 -->
              <div class="inner-table-container">
                <el-table
                  border
                  size="small"
                  row-key="id"
                  height="100%"
                  highlight-current-row
                  :data="scope.row.list"
                >
            
                  <el-table-column fixed prop="id" label="玩家ID" width="200" align="center">
                    <template #default="scope">
                      <p>{
   
   { scope.row.id }}</p>
                    </template>
                  </el-table-column>
                  
                  <el-table-column prop="power" label="玩家战力" width="auto" align="center" show-overflow-tooltip>
                    <template #default="scope">
                      <p style="text-align: left; text-indent: 10px; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{
   
   { scope.row.power }}</p>
                    </template>
                  </el-table-column>

                  <el-table-column fixed="right" label="操作" align="center" width="150">
                    <template #default="scope">
                      <div class="inner-table-container-td__operation">
                        <el-row>
                          <el-col :span="24">
                            <!-- ^ 查看详情 -->
                            <el-tooltip effect="dark" content="查看详情" placement="top" :enterable="false" :hide-after="0">
                              <el-button size="small" type="" style="border: unset" plain circle @click="
                                () => {
                                  log('查看详情 =>', scope.row)
                                }
                              ">
                                <el-icon :size="16"><View /></el-icon>
                              </el-button>
                            </el-tooltip>
                            <!-- / 查看详情 -->
                          </el-col>
                        </el-row>
                      </div>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
              <!-- / 内嵌表格 -->

              <!-- ^ 内嵌分页 -->
              <div class="inner-pagger-container">
                <el-pagination
                  v-if="scope.row.total > 0"
                  small
                  background
                  v-model:current-page="scope.row.pageNumber"
                  v-model:page-size="scope.row.pageSize"
                  :total="scope.row.total"
                  :page-sizes="[10, 20, 50, 100]"
                  layout="total, sizes, prev, pager, next, jumper"
                  @size-change="handleInnerTableSizeChange(scope.row)"
                  @current-change="handleInnerTableCurrentChange(scope.row)"
                />
              </div>
              
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="host" label="游戏服务器名称" width="auto" min-width="400" align="center" show-overflow-tooltip>
          <template #default="scope">
            <p class="outer-table-container-td__name">{
   
   { scope.row.host }}</p>
          </template>
        </el-table-column>

        <el-table-column label="创建时间" width="400" align="center">
          <template #default="scope">
            <div>{
   
   { scope.row.createTime ? scope.row.createTime : '-' }}</div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- / 外层表格 -->

    <!-- 外层分页 -->
    <div class="outer-pagger-container">
      <el-pagination
        small
        background
        :current-page="outerData.pageNumber"
        :page-size="outerData.pageSize"
        :page-sizes="[20, 30, 50, 100]"
        :total="outerData.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleOuterTableSizeChange"
        @current-change="handleOuterTableCurrentChange"
      >
      </el-pagination>
    </div>
    <!-- / 外层分页 -->

  </div>
</template>

<script>
export default {
  data: () => ({

    // 加载标志
    elementLoading: true,

    // 外层数据
    outerData: {
      list: [], // 列表
      selectedList: [], // 已选列表
      expandedKeys: [], // 已展开键集合
      expandedList: [], // 已展开列表
      total: 521, // 总数
      pageNumber: 1, // 当前页
      pageSize: 20, // 页码大小
    },

    // 打印日志
    log: console.log
  }),
  created() {
    this.init()
  },
  mounted() {
  },
  methods: {
    // ---- ---- ---- ---- ^ 事件调用方法 ---- ---- ---- ----

    /**
     * 初始化外层表格
     */
    init() {
      const list = []
      for (let i = 0; i < this.outerData.pageSize; i++) {
        const number = parseInt(Math.random() * 10000) + i
        const row = {
          id: number,
          host: `游戏服务器 - ${number}`,
          createTime: new Date()
        }
        list.push(row)
      }
      this.outerData.list = list
      this.outerData.total = this.outerData.total
      this.elementLoading = false
    },

    /**
     * 外层表格 - 页码改变方法
     */
    handleOuterTableSizeChange(val) {
      this.elementLoading = true
      this.outerData.pageNumber = 1
      this.outerData.pageSize = val
      const frontRecords = this.outerData.pageSize * (this.outerData.pageNumber - 1)
      const remainRecords = this.outerData.total - frontRecords

      let list = []
      if (remainRecords >= this.outerData.pageSize) {  
        for (let i = 0; i < this.outerData.pageSize; i++) {
          const number = parseInt(Math.random() * 10000) + i
          const row = {
            id: number,
            host: `游戏服务器 - ${number}`,
            createTime: new Date()
          }
          list.push(row)
        }
      } else {
        for (let i = 0; i < remainRecords; i++) {
          const number = parseInt(Math.random() * 10000) + i
          const row = {
            id: number,
            host: `游戏服务器 - ${number}`,
            createTime: new Date()
          }
          list.push(row)
        }
      }

      setTimeout(() => {
        this.outerData.list = list
        this.outerData.total = this.outerData.total
        this.elementLoading = false
      }, 200)
    },

    /**
     * 外层表格 - 当前页改变方法
     */
    handleOuterTableCurrentChange(val) {
      this.elementLoading = true
      this.outerData.pageNumber = val
      const frontRecords = this.outerData.pageSize * (this.outerData.pageNumber - 1)
      const remainRecords = this.outerData.total - frontRecords
      
      let list = []
      if (remainRecords >= this.outerData.pageSize) {
        for (let i = 0; i < this.outerData.pageSize; i++) {
          const number = parseInt(Math.random() * 10000) + i
          const row = {
            id: number,
            host: `游戏服务器 - ${number}`,
            createTime: new Date()
          }
          list.push(row)
        }
      } else {
        for (let i = 0; i < remainRecords; i++) {
          const number = parseInt(Math.random() * 10000) + i
          const row = {
            id: number,
            host: `游戏服务器 - ${number}`,
            createTime: new Date()
          }
          list.push(row)
        }
      }

      setTimeout(() => {
        this.outerData.list = list
        this.outerData.total = this.outerData.total
        this.elementLoading = false
      }, 200)
    },

    /**
     * 外层表格 - 展开/收起某一行事件句柄方法
     */
    async handleOuterDataExpandChange(row, expandedRows) {
      this.outerData.expandedList = expandedRows
      const index = this.outerData.expandedList.findIndex((item) => item.id === row.id)
      if (index != -1) {
        // 展开
        this.getPlayerList(row)
      } else {
        // 收起
        row.loading = true
      }
    },

    /**
     * 根据游戏服务器获取玩家列表
     */
    async getPlayerList(row) {
      for (let vo of this.outerData.list) {
        // 匹配游戏服务器
        if (vo.id == row.id) {
          vo.loading = false
          vo.list = [] // 列表
          vo.total = 25 // 总数
          vo.pageNumber = 1 // 当前页
          vo.pageSize = 10 // 页码大小
          const list = []
          for (let i = 0; i < vo.pageSize; i++) {
            const number = parseInt(Math.random() * 100000000) + i
            const row = {
              id: number,
              power: Math.pow(number, 5),
            }
            list.push(row)
          }
          vo.list = list
        }
      }
    },

    /**
     * 内嵌表格 - 页码改变方法
     */
    handleInnerTableSizeChange(row) {
      row.loading = true
      row.pageNumber = 1
      const frontRecords = row.pageSize * (row.pageNumber - 1)
      const remainRecords = row.total - frontRecords
      
      let list = []
      if (remainRecords >= row.pageSize) {
        for (let i = 0; i < row.pageSize; i++) {
          const number = parseInt(Math.random() * 100000000) + i
          const row = {
            id: number,
            power: Math.pow(number, 5),
          }
          list.push(row)
        }
      } else {
        for (let i = 0; i < remainRecords; i++) {
          const number = parseInt(Math.random() * 100000000) + i
          const row = {
            id: number,
            power: Math.pow(number, 5),
          }
          list.push(row)
        }
      }

      setTimeout(() => {
        row.list = list
        row.total = row.total
        row.loading = false
      }, 200)
    },

    /**
     * 内嵌表格 - 当前页改变方法
     */
    handleInnerTableCurrentChange(row) {
      row.loading = true
      const frontRecords = row.pageSize * (row.pageNumber - 1)
      const remainRecords = row.total - frontRecords
      
      let list = []
      if (remainRecords >= row.pageSize) {
        for (let i = 0; i < row.pageSize; i++) {
          const number = parseInt(Math.random() * 100000000) + i
          const row = {
            id: number,
            power: Math.pow(number, 5),
          }
          list.push(row)
        }
      } else {
        for (let i = 0; i < remainRecords; i++) {
          const number = parseInt(Math.random() * 100000000) + i
          const row = {
            id: number,
            power: Math.pow(number, 5),
          }
          list.push(row)
        }
      }

      setTimeout(() => {
        row.list = list
        row.total = row.total
        row.loading = false
      }, 200)
    },
  }
}
</script>

<style lang="less" scoped>
  .index {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;

    // ---- ---- ---- ---- ^ 外层表格 样式 ---- ---- ---- ----
    :deep(.outer-table-container) {
      flex: 1;
      position: relative;
      overflow: hidden;

      .el-table {

        th {

          .cell {
            color: #000;
            font-weight: normal;
            font-size: 13px;
          }
        }

        td {
          padding: 2.5px 0;

          .cell {
            // color: #000;
            font-size: 13px;
            padding: 0;
          }
        }

        
        .outer-table-container-td__playerList {
          height: auto;
          overflow: auto;
          padding: 4px 7px;

          /* ^ 内嵌表格 */
          .inner-table-container {
            position: relative;
            overflow: hidden;

            .el-table {

              th {

                .cell {
                  color: #000;
                  font-weight: normal;
                  font-size: 13px;
                }
              }

              td {
                padding: 2.5px 0;

                .cell {
                  // color: #000;
                  font-size: 13px;
                  padding: 0;
                }
              }

              .el-table__cell {
                // background-color: #f8f8f8;
              }
            }

            /* 操作 */
            .inner-table-container-td__operation {

              .el-button {
                position: relative;
                margin: 0px 1px;
              }
            }
            /* / 操作 */
          }
          /* / 内嵌表格 */

          /* ^ 内嵌分页 */
          .inner-pagger-container {
            position: relative;
            width: 100%;
            height: 26px;
            margin-top: 7px;

            .el-pagination {
              position: absolute;
              top: 0;
              // left: 0;
              right: 0;
              bottom: 0;
              margin: 0 auto;
              width: fit-content;

              .btn-prev, .btn-next, .el-pager li {
                border: 1px solid #dcdfe6;
              }

              .el-pager li.is-active {
                border-color: #5e7ce0;
              }
            }
          }
          /* / 内嵌分页 */
        }

        /* 操作 */
        .operation {

          .el-button {
            position: relative;
            margin: 0px 1px;
          }
        }
        /* / 操作 */
      }
    }
    // ---- ---- ---- ---- / 外层表格 样式 ---- ---- ---- ----

    // ---- ---- ---- ---- ^ 外层分页 样式 ---- ---- ---- ----
    :deep(.outer-pagger-container) {
      padding: 7px 0;
      width: 100%;
      height: 26px;
      position: relative;

      .el-pagination {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: 0 auto;
        width: fit-content;

        .btn-prev, .btn-next, .el-pager li {
          border: 1px solid #dcdfe6;
        }

        .el-pager li.is-active {
          border-color: #5e7ce0;
        }
      }
    }
    // ---- ---- ---- ---- / 外层分页 样式 ---- ---- ---- ----
  }
</style>

2. Efecto de operación

Supongo que te gusta

Origin blog.csdn.net/Cai181191/article/details/132884385
Recomendado
Clasificación