Vue2 + ElementUI -- el-table 的 SimpleTable 封装 变种(自适应高度 - 固定高度篇 - 半灵活)

510 阅读1分钟

专栏

效果

iShot_2024-12-06_15.02.51.gif

解决的问题

  • UI 要求底部分页固定在底部,表格高度自适应,且表格内容区滚动,表头是不动的

思路

  • 借助父级 dom 实现 高度 自适应的 el-table
  • 考虑 resize 的情况,resize 后要重新计算高度问题

实现

  • 让父级 dom 先固定高度(伪的)

  • 采用了 element-resize-detector 监听外层 dom 的 窗口变化, 拿外层dom height 减去分页的高度就是表格区的高度

  • 安装插件 element-resize-detector 地址

npm install element-resize-detector -S
<div class="table-content" ref="myTableRef">
  <CustomTable
    :height="tableHeight"
    :columns="columns"
    :data="tableData"
    :isLoading="loading"
  >
    <template #warn="{scope}">
      <div
        :class="scope.row.is_warn === 1 ? 'warning-text' : 'normal-text'"
      >
        {{ scope.row.is_warn === 1 ? '是' : '否' }}
      </div>
    </template>
  </CustomTable>
  <el-pagination
    class="custom-pagination"
    @size-change="handleSizeChange"
    @current-change="handleCurrentChange"
    :current-page.sync="pageData.pageNum"
    :page-size="pageData.pageSize"
    layout="total, prev, pager, next"
    :total="pageData.total"
    background
  />
</div>
import elementResizeDetectorMaker from 'element-resize-detector';

export default {
    data: () => ({
        erd: elementResizeDetectorMaker(),
        pageData: {
          pageNum: 1,
          pageSize: 10,
          total: 0,
        },
        tableData: [],
        columns: [],
        loading: false,
        paginationHeight: 50, // 分页的高度
        tableHeight: null, // 默认 为 null,使高度不生效
    }),
    mounted() {
        // 获取 外层 dom 高度
        this.onResize()
    },
    methods: {
        getTableData() {
        },
        onResize() {
          this.erd.listenTo(this.$refs.myTableRef, (ele) => {
            this.tableHeight = ele.offsetHeight - this.paginationHeight;
            console.log('<<<<<first>>>>>', this.tableMaxHeight);
          });
        },
        handleSizeChange(val) {
          this.pageData.pageSize = val;
          this.getTableData();
        },
        handleCurrentChange(val) {
          this.pageData.pageNum = val;
          this.getTableData();
        },
    }
}

// 父级 纵向 flex
display: flex;
flex-direction: column;
...

.table-content {
    position: relative;
    flex: 1; // 自动分配剩余部分
    overflow: hidden;
    
    // 分页布局 调整
    .custom-pagination {
      margin-top: 15px;
      display: flex;
      justify-content: flex-end;
      position: relative;
      /deep/ .el-pagination__total {
        position: absolute;
        left: 0;
      }
    }
}