antd穿梭框自定义table下拉加载

473 阅读2分钟

背景

产品需求需要,穿梭框中加载table,并且table可以实现下拉加载,antd官方没有实现这个功能,因此只能自己实现

image.png

难点

  1. 鼠标向下滚动实现自动加载
  2. 当右边选了项目后,左边搜索不能清空右边的选项。

image.png

解决问题

自动加载的问题

自动加载,一开始想到能动的就是最后一列加一个className,利用 oberve去监听

const mockData: RecordType[] = Array.from({ length: 20 }).map((_, i) => ({ 
key: i.toString(), 
title: `content${i + 1}`, 
description: <div className="show">description of content${i + 1}</div>, 
disabled: i % 4 === 0, 
tag: mockTags[i % 3], }));


useEffect(() => {
    const intersectionObserver = new IntersectionObserver(entries => {
        // 如果 intersectionRatio 为 0,则目标在视野外,
        // 我们不需要做任何事情。
        if (entries[0].intersectionRatio <= 0) {return;}
        // 之前先移除 mockdata中的 className=show
        mockData.push(({ 
            key: i.toString(), 
            title: `content${i + 1}`, 
            description: <div className="show">description of content${i + 1}</div>, 
            disabled: i % 4 === 0, 
            tag: mockTags[i % 3], }))
    });
    // 开始监听
    intersectionObserver.observe(dom);
    return () => {
        intersectionObserver.unobserve(dom);
    };
}. [])

这样写完后,发现没效果。寻找原因,使用observe肯定没问题,接下来就从antd table的footer入手,因为table的footer会自动展示在最后一列。

<Table 
    footer={() => <div className="loading"></div>}
/>

useEffect(() => {
    const dom = document.querySelector(`.loafing`) as HTMLElement;
    const intersectionObserver = new IntersectionObserver(entries => {
        // 如果 intersectionRatio 为 0,则目标在视野外,
        // 我们不需要做任何事情。
        if (entries[0].intersectionRatio <= 0) {return;}
        getDataSource();
    });
    // 开始监听
    intersectionObserver.observe(dom);
    return () => {
        intersectionObserver.unobserve(dom);
    };
}, []);

至此自动加载的功能写完了,解决搜索后,选中的内容会被清空的问题

选中的内容被清空的问题

antd的transfer的target(右侧选中的内容)会根据datasource来匹配,当我们进行搜索的时候,datasource会被清空,所以导致右侧选中的内容匹配不上,就也被清空了。要解决这个问题,就只能在搜索为空的时候,把原来的加上去。

// datasource只有选中项目
setDataSource(data => {
    data = data.filter(item => targetKeys.includes(item.key));
    return [...data];
});
getDataSource();

最后

稍微探索了一下,其实observe在移动端用的多,pc端用的相对较少,target等于稍微了解了一下antd transfer的原理,这个最后写成了一个公共组件供后续业务使用。
欢迎大家一起交流。