图片瀑布流+懒加载+无限下滑
import React, { lazy, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import InfiniteScroll from 'react-infinite-scroller';
import Macy from 'macy';
import LazyLoad from 'react-lazy-load';
import { useSetState } from 'react-use';
import { convert } from '@/utils';
import { useDispatch, useRequest, useSelector } from 'umi';
import { Spin } from 'antd';
import { post } from '@/utils/request';
interface EmptyProps {
imgWidth?: number;
innerWidth?: number;
container?: string;
Conmpont?: any;
conHeight?: string;
handlePic?: void;
overPic?: any;
overPicfooter?: any;
margindis?: Object;
columns?: number;
}
const PicMacy: React.FC<EmptyProps> = (props) => {
const {
imgWidth = 360,
innerWidth,
container = 'mainList',
children,
conHeight = 'calc(100vh - 68px)',
overPic = () => {},
overPicfooter = () => {},
handlePic = (val: object) => {},
margindis = { left: 16, top: 16 },
columns = 6,
} = props;
const { userInfo } = useSelector((app) => app.user);
const postqueryPicByLabelOrNot = (data) =>
post('PortalPic/queryPicByLabelOrNot', data);
const [scroller, setScroller] = useState({ isLastPage: false });
const pageNum = useRef(1);
const hasMore = useRef(true);
const [imgList, setImgList] = useState([]);
const postqueryPicByLabelOrNotRequest = useRequest(postqueryPicByLabelOrNot, {
manual: true,
onSuccess: (data) => {
if (data.list.length > 0) {
pageNum.current = pageNum.current + 1;
hasMore.current = true;
setScroller(data);
setImgList([...imgList, ...data?.list]);
getMacy();
}
},
});
let masonry: any = null;
const getMacy = () => {
if (masonry) {
masonry.reInit();
} else {
masonry = new Macy({
container: `#${container}`,
trueOrder: false,
waitForImages: false,
useOwnImageLoader: false,
debug: true,
columns: columns,
margin: { x: margindis.left, y: margindis.top },
});
}
};
useEffect(() => {
lazyload();
}, [imgList]);
const lazyload = () => {
const ob = new IntersectionObserver(
(entries) => {
for (let entry of entries) {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
ob.unobserve(img);
getMacy();
}
}
},
{
root: null,
rootMargin: '0px 0px 100px 0px',
threshold: [0, 0.1],
},
);
const imgs = document.querySelectorAll('img[data-src]');
imgs.forEach((item) => {
ob.observe(item);
});
};
const getMore = () => {
hasMore.current = false;
if (userInfo.userId && !scroller.isLastPage) {
postqueryPicByLabelOrNotRequest.run({
currentPage: pageNum.current,
userId: '1722523689024618496',
pageSize: 50,
});
}
};
useEffect(() => {
if (userInfo.userId) {
getMore();
}
}, [userInfo]);
return (
<div className={styles.PicMacyLayout} style={{ height: conHeight }}>
{children}
<InfiniteScroll
className="list-contents"
initialLoad={true}
pageStart={1}
loadMore={async () => await getMore()}
loader={
!scroller.isLastPage && (
<div style={{ textAlign: 'center' }}>
<Spin spinning={true}></Spin>
</div>
)
}
useWindow={false}
hasMore={hasMore.current}
>
<div className={styles.recomandList} id={container} ref={scroll}>
{imgList?.map((item, index) => {
return (
<div className={styles.item_box}>
<div className={styles.recomandItem} key={index}>
<img
src={
'https://img0.baidu.com/it/u=1035818712,4106770352&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800'
}
className={styles.item_img}
data-src={item.pictureUrl}
style={{ width: `${convert(imgWidth)}` }}
onClick={() => handlePic(item)}
/>
<div className={styles.overpic}>{overPic(item)}</div>
<div className={styles.overpic_footer}>
{overPicfooter(item)}
</div>
</div>
</div>
);
})}
</div>
{scroller.isLastPage && (
<div style={{ textAlign: 'center' }}>到底啦~</div>
)}
</InfiniteScroll>
</div>
);
};
export default PicMacy;
@import '../../assets/util.less';
.PicMacyLayout {
overflow: auto;
.recomandItem {
position: relative;
.overpic {
position: absolute;
top: 0px;
visibility: hidden;
}
.overpic_footer {
position: absolute;
bottom: 0px;
visibility: hidden;
}
}
.item_img {
background: linear-gradient(0deg, #000000 0%, rgba(0, 0, 0, 0.43) 72%);
border-radius: 14px;
}
.recomandItem:hover {
.overpic {
visibility: visible;
}
.overpic_footer {
visibility: visible;
}
cursor: pointer;
}
}