专栏
- Vue2 + ElementUI -- el-table 的 SimpleTable 封装
- Vue2 + ElementUI -- el-table 的 SimpleTable 封装 变种(支持滚动加载)
- Vue2 + ElementUI -- el-table 的 SimpleTable 封装 变种(自适应高度 - 固定高度篇 - 半灵活)
- Vue2 + ElementUI -- el-table 的 SimpleTable 封装 变种(自适应高度 - 固定高度篇 - 全灵活)
效果
解决的问题
UI
要求底部分页跟随表格高度,达到内容区的最大高度时,采用滚动展示数据
思路
- 不让使用固定高度,高度应是动态的
- 考虑
resize
的情况,resize
后要重新计算高度问题
实现
-
让父级
dom
先固定高度(伪的) -
需要已知
table
中的 表头高度 和 行高,通过数据长度得到表格的高度,同时和外层dom的高度做比较,如果超出则滚动 -
此区域是
flex: 1;
实现的自适应区域,高度可变,当变化时要触发重新计算,为了提高性能,减少计算次数,所以采用了element-resize-detector
监听外层dom
的 窗口变化,当外层的dom尺寸变化的时候触发el-table
的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(),
tableMaxHeight: null,
pageData: {
pageNum: 1,
pageSize: 10,
total: 0,
},
tableData: [],
columns: [],
loading: false,
tableHeaderHeight: 60, // 表格 header 高度
tableRowHeight: 60, // 表格的行高
paginationHeight: 50, // 分页的高度
}),
computed: {
tableHeight() {
if (this.tableMaxHeight == null) {
return null;
}
const len = this.tableData.length;
return (len * this.tableRowHeight + this.tableHeaderHeight) > this.tableMaxHeight ? this.tableMaxHeight : null;
},
},
mounted() {
// 获取 外层 dom 高度
this.onResize()
},
methods: {
getTableData() {
},
onResize() {
this.erd.listenTo(this.$refs.myTableRef, (ele) => {
this.tableMaxHeight = 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;
}
}
}