/*
|
* @Company: hugeInfo
|
* @Author: ldh
|
* @Date: 2022-08-09 08:32:43
|
* @LastEditTime: 2023-10-07 10:23:09
|
* @LastEditors: dminyi 1301963064@qq.com
|
* @Version: 1.0.0
|
* @Description: 虚拟滚动列表
|
*/
|
import React, { useRef, useEffect } from 'react';
|
import { Spin } from 'dingtalk-design-mobile';
|
import './index.less';
|
import routerStatus from '../../status/router';
|
|
/**
|
* data: array, // 列表数据
|
* height: string | number // 父容器高度
|
* loadMore: func // 加载更多的回调方法
|
* AddStyle: object // 列表项的样式
|
* hasMore: bool // 是否显示加载更多
|
* itemDom: func // 列表项的dom
|
* bottomText: string // 底部显示文本
|
* threshold: number // 距离底部多少px触发loadMore
|
* getScrollTopKey: string // 是否开启滚动条位置保存,保存的key
|
* scrollTop: number // 滚动条位置
|
*/
|
const MyList = ({ data, dataTotal, AddStyle, height, loadMore, hasMore, itemDom, bottomText, threshold = 150, getScrollTopKey, scrollTop,showBottomText }) => {
|
const parentRef = useRef();
|
|
// 触底加载
|
useEffect(() => {
|
parentRef.current.onscroll = () => {
|
if (getScrollTopKey) {
|
// console.log('getScrollTopKey', getScrollTopKey)
|
// console.log('parentRef', parentRef);
|
// console.log('parentRef.current?.scrollTop', parentRef.current?.scrollTop)
|
routerStatus.setPageScrollTop(getScrollTopKey, parentRef.current?.scrollTop);
|
}
|
if (routerStatus.loadBottom || !hasMore || !loadMore) return;
|
if (parentRef.current.scrollTop > parentRef.current.scrollHeight - parentRef.current.clientHeight - Number(threshold)) {
|
routerStatus.setLoadBottomStatus(true)
|
// 返回一个callback来更新触底的状态,不再继续滚动刷新
|
loadMore(function () {
|
routerStatus.setLoadBottomStatus(false)
|
});
|
}
|
};
|
}, [hasMore, loadMore, threshold]);
|
|
// 设置滚动条位置
|
useEffect(() => {
|
if (!!scrollTop) {
|
setTimeout(() => {
|
parentRef.current.scrollTop = scrollTop;
|
// console.log('scrollTop', scrollTop);
|
// console.log('parentRef.current.scrollTop', parentRef.current.scrollTop);
|
routerStatus.clearPageScrollTopNow();
|
}, 200);
|
}
|
}, [scrollTop]);
|
|
return (
|
<div className="myList" style={{ height: height || '100%', ...AddStyle }} ref={parentRef}>
|
{data.map((x, t) => (
|
<div key={t}>{itemDom(x, t)}</div>
|
))}
|
<div className="myList-loading">
|
{hasMore ? (
|
<>
|
<Spin className="myList-loading-spin" />
|
<div>努力加载中</div>
|
</>
|
) : (
|
// <>{bottomText || `共${dataTotal || data.length}条记录`}</>
|
<>{showBottomText !== false && '已加载全部数据'}</>
|
)}
|
</div>
|
</div>
|
);
|
};
|
|
// TODO:项目本想使用虚拟滚动,但奈何与CacheRoute联合使用时,进入到页面中返回到list页面时滚动条回位不成功所以放弃使用。
|
// const rowVirtualizer = useVirtual({
|
// size: data.length,
|
// parentRef: parentRef,
|
// overscan: 5,
|
// });
|
// {/* <div style={{ height: rowVirtualizer.totalSize, width: '100%', position: 'relative' }}>
|
// {rowVirtualizer.virtualItems.map((virtualRow) => {
|
// let x = data[virtualRow.index];
|
// return (
|
// <div
|
// key={virtualRow.index}
|
// ref={virtualRow.measureRef}
|
// style={{
|
// position: 'absolute',
|
// top: 0,
|
// left: 0,
|
// width: '100%',
|
// transform: `translateY(${virtualRow.start}px)`,
|
// }}
|
// >
|
// {itemDom(x, virtualRow.index)}
|
// </div>
|
// );
|
// })}
|
// </div>; */}
|
|
export default MyList;
|