使用ElementPlus实现内嵌表格和内嵌分页

news2024/9/26 5:14:01

前言

有时遇到这样的需求,就是在表格里面嵌入一个表格,以及要求带有分页,这样在ElementPlus中很好实现。以下使用Vue2语法实现一个简单例子,毕竟Vue3兼容Vue2语法,若想要Vue3版本例子,简单改改就OK了。

一、示例代码

(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>

二、运行效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1019063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——图的应用

文章目录 前言一、图的应用1. 最小生成树普里姆&#xff08;Prim&#xff09;算法克鲁斯卡尔&#xff08;Kruskal&#xff09;算法 2. 最短路径Dijkstra算法求单源最短路径 3. 拓扑结构4. 关键路径 总结 前言 图的应用 1.1 最小生成树 1.2 最短路径 1.3 拓扑结构 1.4 关键路径…

【网络教程】揭秘Windows SSH服务端免密登录:告别繁琐,享受安全连接

文章目录 开启Windows下的SSH服务端图形界面安装手动下载安装Windows如何查看系统用户名Windows如何查看本机IP开启免密登录Window生成秘钥Linux下生成秘钥配置公钥视频讲解开启Windows下的SSH服务端 这篇文章演示的环境是Windows11Windows的SSH服务端默认情况下是没有安装的,…

9.项目细节调整

文章目录 学习资料项目整体细节调整处理首页 学习资料 https://www.bilibili.com/video/BV13g411Y7GS/?p24&spm_id_frompageDriver&vd_sourceed09a620bf87401694f763818a31c91e 项目整体细节调整 处理首页 默认的首页 肯定不能给人看。文件在这个位置。 可以删除…

live555 BasicUsageEnvironment目录解读

文章目录 BasicUsageEnvironmentBasicHashTable.cppBasicTaskScheduler.cppBasicTaskScheduler0.cppBasicUsageEnvironment.cppBasicUsageEnvironment0.cppDelayQueue.cpp后续会进行更新 BasicUsageEnvironment ├── BasicHashTable.cpp ├── BasicTaskScheduler0.cpp ├─…

类加载器 - 双亲委派模型

文章目录 回顾一下类加载过程类加载器类加载器介绍类加载器加载规则类加载器总结自定义类加载器 双亲委派模型双亲委派模型介绍双亲委派模型的执行流程双亲委派模型的好处打破双亲委派模型方法 本文参考&#xff1a; 类加载器详解&#xff08;重点&#xff09; | JavaGuide(Ja…

多目标优化算法:基于非支配排序的海象优化算法(NSWOA)MATLAB

一、海象优化算法WOA 海象优化算法&#xff08;Walrus Optimization Algorithm&#xff0c;WOA&#xff09;由Trojovsk等人于2023年提出&#xff0c;该算法模拟海象的进食&#xff0c;迁移&#xff0c;逃跑和对抗捕食者的过程&#xff0c;WOA包含探索、迁移和开发三个阶段&…

正则表达式学习和高级用法

以下所有的验证都在 在线验证 1. 起始符 / 正则表达式的起始符2. 限定符 匹配前面的子表达式**1次或多次**。例如&#xff0c;zo 能匹配 "zo" 以及"zoo"&#xff0c;但不能匹配 "z"。等价于 {1,}。 ? 匹配前面的子表达式**0次或1次**。例如…

二进制 Deploy Kubernetes v1.23.17 超级详细部署

文章目录 1. 预备条件2. 基础配置2.1 配置root远程登录2.2 配置主机名2.3 安装 ansible2.4 配置互信2.5 配置hosts文件2.6 关闭防firewalld火墙2.7 关闭 selinux2.8 关闭交换分区swap2.9 修改内核参数2.10 安装iptables2.11 开启ipvs2.12 配置limits参数2.13 配置 yum2.14 配置…

函数防抖和节流

函数防抖和节流 经典真题 防抖&#xff0c;节流是什么&#xff0c;如何实现 &#xff08;字节&#xff09; 什么是函数防抖和节流 JavaScript 中的函数大多数情况下都是由用户主动调用触发的&#xff0c;除非是函数本身的实现不合理&#xff0c;否则一般不会遇到跟性能相关…

DMA简单总结

文章目录 一、基础概念1.1 DMA---Direct Memory Access 直接存储器访问&#xff0c;目的减少CPU资源占用 二、典型DMA硬件模型2.1 基本硬件特性---通道数、源/目标类型&#xff0c;地址与累加方式&#xff0c;数据位宽&#xff0c;搬移长度&#xff0c;循环模式&#xff0c;中断…

在c#中使用CancellationToken取消任务

目录 &#x1f680;介绍&#xff1a; &#x1f424;简单举例 &#x1f680;IsCancellationRequested &#x1f680;ThrowIfCancellationRequested &#x1f424;在控制器中使用 &#x1f680;通过异步方法的参数使用cancellationToken &#x1f680;api结合ThrowIfCancel…

‘XXX’ is already defined @typescript-eslint/no-redeclare 警告 问题解决

上文ReactTypescript项目环境中搭建并使用redux环境 结束是 其实不算完全写完吧 还会留下一个警告 这个报错 好像是说 这两个值已经定义过了 可能很多人 会觉得小问题 但你会发现 无论你名字怎么改都会一直 带着你新的名字继续报错 我们可以多套一层 export namespace Const…

Java8实战-总结29

Java8实战-总结29 并行数据处理与性能并行流将顺序流转换为并行流测量流性能 并行数据处理与性能 到目前为止&#xff0c;Stream接口最重要的好处是可以对这些集合执行操作流水线&#xff0c;能够自动利用计算机上的多个内核。 例如&#xff0c;在Java 7之前&#xff0c;并行…

Python 异常的概念

视频版教程 Python3零基础7天入门实战视频教程 异常是指程序运行的过程中出现了错误&#xff0c;也叫Bug。 案例一&#xff1a; # 定义人类 class Person:# 属性 姓名name None# 属性 年龄age Noneprint(Person().sex)因为Person类没有sex属性&#xff0c;对象访问sex属性…

Go语言开发环境搭建指南:快速上手构建高效的Go开发环境

Go 官网&#xff1a;https://go.dev/dl/ Go 语言中文网&#xff1a;https://studygolang.com/dl 下载 Go 的语言包 进入官方网站 Go 官网 或 Go 语言中文网&#xff1a; 选择下载对应操作系统的安装包&#xff1a; 等待下载完成&#xff1a; 安装 Go 的语言包 双击运行上…

HuggingFace Transformer

NLP简介 HuggingFace简介 hugging face在NLP领域最出名&#xff0c;其提供的模型大多都是基于Transformer的。为了易用性&#xff0c;Hugging Face还为用户提供了以下几个项目&#xff1a; Transformers(github, 官方文档): Transformers提供了上千个预训练好的模型可以用于不…

GitHub 曝出漏洞,或导致 4000 多个存储库遭受劫持攻击

The Hacker News 网站披露&#xff0c;安全研究员发现 GitHub 中存在一个新安全漏洞&#xff0c;该漏洞可能导致数千个存储库面临劫持攻击的风险。据悉&#xff0c;在 2023 年 3 月 1 日漏洞披露后&#xff0c;微软旗下的代码托管平台已于 2023 年 9 月 1 日解决了安全漏洞问题…

无涯教程-JavaScript - FACT函数

描述 The FACT function returns the factorial of a number. The factorial of a number is equal to 1&ast;2&ast;3&ast;...&ast; number. 语法 FACT (number)争论 Argument描述Required/OptionalNumberThe nonnegative number for which you want the f…

LeetCode 39. Combination Sum【回溯,剪枝】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

C#小知识

项目编译后复制文件到生成目录 方法1 对于单个文件&#xff0c;可以点击属性。输出目录里选择始终复制。 方法2 把项目中的ServerScripts复制到输出目录。 在项目设置中&#xff0c;生成事件里添加批处理 xcopy $(ProjectDir)ServerScripts\*.* $(TargetDir)ServerScrip…