闻心阁

一蓑烟雨看苍生,半壶浊酒笑红尘

Ant Design中实现表格的滚动加载

2022-05-29 约 1 分钟读完 搬砖秘籍

表格是我们做企业信息中最常用的前端组件之一,最近的一个需求中,客户提出了这样的一个需求:

你们表格的分页太麻烦了,我就想打开就看到所有数据,不要说xxxx不支持,我们以前用的xxxx系统就是这样的。

需求分解

客户真的需要一打开就看到所有数据吗?

并不是。

为什么这么说呢?因为所有的数据一次查询几千条,后面也有可能上万条。客户就算多长2个眼睛,一眼也不可能看得完这么数据,就算看得完,显示器也显示不完,接电视也不行。

所以我猜测客户真正想要的是什么:不想分页。

于是找了那个所谓的xxx系统看了一眼,果然就是如此,不过就是把分页换成了滚动加载。

解决方案

识别到了用户真正的需求,后面就是解决问题了,查了一个Ant Design的API文档,很遗憾,原生并不支持这个功能,但客户又着急解决问题,所以先用了一种hack的方式。

简要的代码如下:

class xxxx extends Component {
  constructor(props, context){
    super(props, context);
    this.state = {
      isShowModal: false
    };
    this.scrollLoading = debounce(this.scrollLoading.bind(this), 100); //bind function once
  }

  componentDidMount(){
    document.querySelector('.ant-table-body')
      .addEventListener('scroll', this.scrollLoading);
  }

  componentWillUnmount() {
    document.querySelector('.ant-table-body')
      .removeEventListener('scroll', this.scrollLoading);
  }

  scrollLoading (e) {
    const scrollTop = get(e, 'target.scrollTop', 0);
    const clientHeight = get(e, 'target.clientHeight', 0);
    const scrollHeight = get(e, 'target.scrollHeight', 0);
    const pageNum = get(this.stores, 'state.pageConfig.current', 1);
    const pageSize = get(this.stores, 'state.pageConfig.pageSize', 0);
    const total = get(this.stores, 'state.tableData.total', 0);

    if (!scrollLoading && (scrollTop + clientHeight >= scrollHeight - 100) && (pageNum * pageSize < total)) {
      scrollLoading = true;
      this.getList({
        pageNum: pageNum + 1
      }).then(() => {
        scrollLoading = false;
      });
    }
  }

  render() {
    // page code here
  }

简要解释一下上述代码。

  1. 构造函数的时候使用debounce函数做一个防抖,提升性能。
  2. 在页面加载完成后,监听antd中Table组件的scroll事件,并将滚动加载的函数注册到回调中。
  3. 页面滚动的时候触发scrollLoading函数,对当前页面的滚动状态做个计算,在计算发现用户快滚动到底部的时候,触发分页加载。
  4. 在页面销毁的时候取消监听,防止内存泄漏。

存在的问题

上面的代码可以解决客户的燃眉之急,但其实有不少问题。

  1. 页面存在多个表格会有冲突。
  2. 页面性能低下,数据量大的时候,滚动会有延迟。
  3. 后端接口速度不给力,还是能让用户感知到在加载行为。

下一步规划

针对上述问题,也有一些解决方案。

  1. 给每个表格手动传入一个id
  2. 加入虚拟滚动(在G3组件库的版本中已经添加)提高性能
  3. 与后端配合,提升加载速度
  4. G3组件库封装,原生支持分页和滚动加载两种模式。

更多的解决方案还请大家多多留言指教。