背景
产品需求需要,穿梭框中加载table,并且table可以实现下拉加载,antd官方没有实现这个功能,因此只能自己实现
难点
- 鼠标向下滚动实现自动加载
- 当右边选了项目后,左边搜索不能清空右边的选项。
解决问题
自动加载的问题
自动加载,一开始想到能动的就是最后一列加一个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的原理,这个最后写成了一个公共组件供后续业务使用。
欢迎大家一起交流。