纯CSS使Element Table自适应高度

7,124 阅读3分钟

背景

项目使用了element-ui组件库,其中table使用得很频繁。在使用过程中,我发现,要使得表格自适应且表头固定,必须要传入height。由于table的高度不是一个固定的值,它会随着屏幕的大小而变化,这就导致了一个问题: 每增加一个表格,都必须写入以下内容:

  1. js计算table的高度
  2. 监听窗口的resize事件,每次resize后做步骤1的操作
  3. 页面销毁时也要去掉事件监听防止内存泄漏

具体实现可以参考各位掘友的实现:Element Table 自适应高度解决方案。这篇文章讲得很详细。不过在表格变得越来越多时,代码似乎就变得不那么容易维护了,此时我萌生了一个用纯CSS使Element Table自适应高度的念头。

探索实现

我的想法是通过设置父容器为flex布局,然后el-table的flex设为1。使得el-table自动撑开。不过在控制台上可以查看到,el-table的源码中flex本身就为1,所以省去了设置flex: 1这一步。

<div id="app">
 <el-table
  border
  class="table-test"
  :data="tableData"
>
  <el-table-column prop="date" label="日期" width="180"> </el-table-column>
  <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
  <el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
</div>

#app {
  height: 90vh;
  border: 1px solid;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
var Main = {
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }]
      }
    }
  }
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')

但是这样的操作是不行的,我们查看元素可以看到,table虽然是刚好占据了整个父容器的高度,但是里面的节点却超出了容器,并且没有出现滚动条。如下两张图:

table占满容器高度(父容器 border: 1px solid):

table里body的内容超出table且并未出现滚动条:

为了解决这个问题,在阅读element-ui源码后我发现,height属性会用于高度计算,会影响上图中的el-table__body-wrapper

于是我将height="100%"传入el-table中,用于el-table组件库内做高度计算。果然就能实现table的固定表头自适应了。尝试将一些其他东西也加入同一个父容器中,也依旧能保持表格自适应。只需这两部:

  1. 父容器display: flex
  2. el-table设置height=100%

上图的html完整代码如下:

<div id="app">
<div><el-button>测试2</el-button></div>
 <el-table
  border
  class="table-test"
  :data="tableData"
  height="100%"
>
  <el-table-column prop="date" label="日期" width="180"> </el-table-column>
  <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
  <el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
<el-pagination></el-pagination>
</div>

完整代码

具体代码查看这里codepen,可通过调整屏幕高度感受table的自适应高度。

结语

通过CSS设置Table的自适应高度,将大量的不易维护的js计算高度的代码完全移除了,代码变得更优雅,也更方便后续快速迭代需求。