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

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

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

需求分解

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

并不是。

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

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

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

解决方案

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

简要的代码如下:

 1class xxxx extends Component {
 2  constructor(props, context){
 3    super(props, context);
 4    this.state = {
 5      isShowModal: false
 6    };
 7    this.scrollLoading = debounce(this.scrollLoading.bind(this), 100); //bind function once
 8  }
 9
10  componentDidMount(){
11    document.querySelector('.ant-table-body')
12      .addEventListener('scroll', this.scrollLoading);
13  }
14
15  componentWillUnmount() {
16    document.querySelector('.ant-table-body')
17      .removeEventListener('scroll', this.scrollLoading);
18  }
19
20  scrollLoading (e) {
21    const scrollTop = get(e, 'target.scrollTop', 0);
22    const clientHeight = get(e, 'target.clientHeight', 0);
23    const scrollHeight = get(e, 'target.scrollHeight', 0);
24    const pageNum = get(this.stores, 'state.pageConfig.current', 1);
25    const pageSize = get(this.stores, 'state.pageConfig.pageSize', 0);
26    const total = get(this.stores, 'state.tableData.total', 0);
27
28    if (!scrollLoading && (scrollTop + clientHeight >= scrollHeight - 100) && (pageNum * pageSize < total)) {
29      scrollLoading = true;
30      this.getList({
31        pageNum: pageNum + 1
32      }).then(() => {
33        scrollLoading = false;
34      });
35    }
36  }
37
38  render() {
39    // page code here
40  }

简要解释一下上述代码。

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

存在的问题

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

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

下一步规划

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

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

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