返回 导航

其他

hangge.com

Vue.js - 实现Table表格内容区域按行滚动效果(Element UI)

作者:hangge | 2021-12-21 08:10
    当我们使用 Element UITable 表格组件,如果内容条目超出显示区域则会自动出现滚动条。但默认情况下,滚动条是线性滚动的,也就是说滚动停止时表格最上方可能出现只显示半行的情况:

如果希望无论怎么滚动,第一行都能够完整显示,只需监听内容区域的滚动事件,然后自动设置合适的垂直滚动条位置即可。

1,样例代码

<template>
  <div class="hello">
    <el-table id="table1" ref="table"
          :data="tableData" height="250"
          style="width: 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>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
      return {
      }
  },
  computed: {
    tableData() {
      let data = [];
      for (var i=1; i<31; i++) {
        data.push({
          date: '2021-12-' + i,
          name: '王小虎' + i,
          address: '上海市普陀区金沙江路 1516 弄'
        });
      }
      return data;
    }
  },
  mounted() {
      // 拿到表格挂载后的真实DOM
      const table = this.$refs.table;
      // 拿到表格中承载数据的div元素
      const bodyWrapper = table.bodyWrapper;
      // 监听滚动事件
      bodyWrapper.onscroll = () => {
        // 滚动条位置强制设置指定行上边缘(48为行高)
        bodyWrapper.scrollTop = Math.round(bodyWrapper.scrollTop / 48) * 48; 
      }
  }      
}
</script>

2,效果图

    运行结果如下,可以看到无论是通过鼠标滚轮,还是拖动右侧滚动条,表格显示区域最上面一行总能完全显示,不会出现只显示一部分的情况。

功能改进:自动为内容区域的底部添加外边距

(1)上面代码还有个小问题,就是如果表格内容显示区域的高度并不能被行高整除,那么当滚动到底部时,最上方仍然会出现显示不完全的一行。

(2)为解决这个问题,我们可以给内容下方添加一些边距,确保滚动条能够继续向下滚动:
<template>
  <div class="hello">
    <el-table id="table1" ref="table"
          :data="tableData" height="250"
          style="width: 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>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
      return {
      }
  },
  computed: {
    tableData() {
      let data = [];
      for (var i=1; i<31; i++) {
        data.push({
          date: '2021-12-' + i,
          name: '王小虎' + i,
          address: '上海市普陀区金沙江路 1516 弄'
        });
      }
      return data;
    }
  },
  mounted() {
      // 拿到表格挂载后的真实DOM
      const table = this.$refs.table;
      // 拿到表格中承载数据的div元素
      const bodyWrapper = table.bodyWrapper;
      // 获取内容显示区域高度,并设置下外边距(设置个延时,否则获取不到高度)
      setTimeout(()=>{
        // 获取显示区域高度
        const bodyHeight = bodyWrapper.clientHeight;
        // 获取实际内容元素
        const content = table.bodyWrapper.firstChild;
        // 给实际内容元素添加下外边距
        content.style["margin-bottom"] = (bodyHeight % 48) + 'px';
      }, 200);      
      // 监听滚动事件
      bodyWrapper.onscroll = () => {
        // 滚动条位置强制设置指定行上边缘(48为行高)
        bodyWrapper.scrollTop = Math.round(bodyWrapper.scrollTop / 48) * 48; 
     }
  }      
}
</script>

(3)运行结果如下:
评论

全部评论(0)

回到顶部