vue3 + element-plus + el-table 实现三层嵌套表格(含分页)

概述

项目需求 表格嵌套表格,一共三层表格,第二层基于第一层数据显示(流加载),第三层基于第二层数据(分页加载)。一下实现效果ui图! 日常需求小记录!佛系记录!
在这里插入图片描述
首先我这里使用的是 element-plus 的表格去实现的(含有扩展行 expand配置项),这个图没什么难得,就是逻辑交互可能稍微复杂一点!

先看第一层代码:

// row-key="" 绑定唯一性id值      
// expand-row-keys 这个配置展开得行     
// @expand-change扩展行变化 可在官网查看
// 控制第二层得展开 和获取
<el-table
        :data="state.deptListData"
        stripe
        border
        class="flex1"
        height="100%"
        row-key="deptId"
        :header-cell-style="{ 'text-align': 'center' }"
        v-loading="state.deptLoading"
        :expand-row-keys="policeState.deptExpands"
        @expand-change="deptExpandsChange"
      >

		<el-table-column type="expand">
          <!--第二层嵌套 民警-->
          <template #default="{ row }">
          	<!--流加载配置   loadPoliceList 滚动条拉到底部触发 请求第二页数据-->
          	<!--通过 police-box css设置固定高度,因为要用流加载   ofa:overflow: auto;  dn-scroll:隐藏滚动条-->
            <div
              class="police-box ofa dn-scroll"
              v-infinite-scroll="loadPoliceList"
              :infinite-scroll-distance="15"
              :infinite-scroll-delay="300"
              :infinite-scroll-immediate="false"
            >
			<!--这里跟第一层是一样得 控制第三层得展开和获取-->
              <el-table
                v-if="policeState.policeChildren.length"
                :data="policeState.policeChildren"
                :show-header="false"
                class="police-table"
                row-key="investigatorBadgeNum"
                :expand-row-keys="suspectState.policeExpands"
                @expand-change="policeExpandsChange"
              >
                <el-table-column type="expand">
                  <!--第三层嵌套 嫌疑人-->
                  <template #default="{ row }">
                    <el-table
                      :data="suspectState.suspectChildren"
                      :cell-style="{ 'text-align': 'center' }"
                      :header-cell-style="{ 'text-align': 'center' }"
                    >
                      <!--第三层的列   这里并没有设置暂无数据,因为在全局表格中已经通过css 设置过了,你这里如果没设置,可以加上-->
                    </el-table>

					<!--封装的分页 没有数据就不显示分页-->
                    <Pagination
                      v-show="suspectState.suspectChildren.length"
                      :pageSizes="[10, 20, 30]"
                      :pageData="suspectState.suspectPageData"
                      @filter="getSuspectList"
                    ></Pagination>
                  </template>
                </el-table-column>

                <!--第二层其余列数据-->
              </el-table>
              <div v-else class="h100 w100 flex flex-center">暂无数据</div>
            </div>
          </template>
        </el-table-column>


	<!--这里就是第一层其他列内容-->
</el-table>

// 流加载触发函数
const loadPoliceList = () => {
  if (policeState.policeChildren.length >= policeState.policePageData.total)
    return
  policeState.policePageData.pageNum += 1
  // 这里请求第二层数据
}


// 点击第一层 展开 收缩事件   第三层也照例就ok了
const deptExpandsChange = async (row: any, expandedRows: any) => {
// 重置查询条件  因为每个第二层都是公用的同一个分页
  policeState.policeChildren = []
  policeState.policePageData = {
    pageNum: 1,
    pageSize: 10,
    total: 0,
  }
  // 需关闭其他扩展行 保持一个扩展行的使用  子扩展行也要收缩
  suspectState.policeExpands = []
  policeState.deptExpands = []
  if (expandedRows.length) {
    if (row) {
      policeState.deptExpands.push(row.deptId)
      policeState.deptExpandCode = row.deptCode // 第二层所需参数
      // 这里去请求 第二层数据
      ...
    }
  }
}

// 第三层
const policeExpandsChange = async (row: any, expandedRows: any) => {
  // 不管折叠 还是展开,必须重置当前分页 及 数据列表
  suspectState.suspectChildren = []
  suspectState.suspectPageData = {
    pageNum: 1,
    pageSize: 10,
    total: 0,
  }
  suspectState.policeExpands = []
  // 展开
  if (expandedRows.length) {
    if (row) {
      suspectState.policeExpands.push(row.investigatorBadgeNum)
      suspectState.policeDeptId = row.deptId // 入参
      suspectState.policeEnterAreaIds = row.enterAreaIds // 入参
      // 这里去请求 嫌疑人数据
    }
  }
}

这个简单的小需求就实现啦!

那个第二层数据 流加载,要确保有一定的高度哈!

注意点: 确保只能张开当前分级 的一个扩展行(因为公用的同一个分页及页码,)。确保每次展开收起 都要将子级收缩起来,并且要把数据及入参清空! 当然如果你想要多个行并列展开的话,有一个思路就是将分页 及 相关参数存到每条数据里,要将数据初始化好!这样及可以展开多行切不互相影响!

如果有什么不足的地方,欢迎指出,谢谢!欢迎评论区留言!

### Vue3 Element Plus Table 表头纵向布局实现Vue3与Element Plus框架下,要实现`el-table`组件的表头纵向布局,可以借鉴HTML原生表格的设计思路[^1]。通常情况下,`el-table`默认支持的是横向表头展示方式;然而通过调整数据结构以及利用CSS样式自定义功能,则能够达到纵向排列的效果。 对于想要创建具有纵向表头样式的表格而言,核心在于改变原本的数据绑定模式——不再是按照行来组织数据项而是依据列来进行划分。具体来说,在准备用于渲染表格的数据源时,应该构建一个多维数组或对象列表形式的数据集,其中每一项代表一整列而非传统意义上的一行记录。 为了更好地理解如何操作,请参见下面给出的一个简单实例: ```javascript // 假设这是我们的原始数据 const rawData = [ { name: 'Alice', age: 24, address: 'Beijing' }, { name: 'Bob', age: 27, address: 'Shanghai' } ]; // 转换成适合纵向表头的形式 const transformedData = Object.keys(rawData[0]).map(key => ({ label: key, values: rawData.map(item => item[key]) })); ``` 接着就是关于模板部分了。这里会采用嵌套循环的方式来遍历转换后的数据并将其映射到相应的UI元素上。值得注意的是,由于Element UI并没有直接提供针对这种情况的支持选项,因此可能还需要额外编写一些定制化的样式规则以确保最终呈现效果符合预期。 ```html <template> <div class="vertical-header-table"> <!-- 使用 div 或其他容器模拟 table 结构 --> <div v-for="(column, columnIndex) in columns" :key="columnIndex" class="table-column"> <span>{{ column.label }}</span> <!-- 显示列名作为表头 --> <ul> <li v-for="(value, rowIndex) in column.values" :key="rowIndex">{{ value }}</li> </ul> </div> </div> </template> <script setup lang="ts"> import { ref } from "vue"; let columns = ref([ { label: "Name", values: ["Alice", "Bob"] }, { label: "Age", values: [24, 27] }, { label: "Address", values: ["Beijing", "Shanghai"] } ]); </script> <style scoped> .vertical-header-table .table-column { float: left; } .table-column span { font-weight: bold; } </style> ``` 上述代码片段展示了怎样基于给定的数据模型构造出一个具备基本交互能力的垂直方向上的表头表格。当然这只是一个非常基础的例子,实际应用当中或许还会涉及到更复杂的场景比如分页、筛选等功能集成等问题[^2]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值