React & TDesign | 多尺寸无限瀑布流图库

2024-05-16 22:50:54 浏览数 (2)

前言

在刷某些App的时候经常遇到双列Feed流的模式,因为UGC的尺寸不一致,还会有不对齐的方式来展示。

双列Feed流双列Feed流

经常写业务的我,对这种东西充满好奇,所以本文就是简单实践探索一下。

实战演练

环境准备

  • Node:18
  • React:18
  • TDesign React:1.7 (TDesign 腾讯企业级设计体系)

UGC展示卡片

最终目标

卡片卡片

用到了TDesignCard 卡片ImageView 图片预览Comment 评论等组件

ImageView 的使用

这个组件是一个可以快速预览的图片,同时支持多张的相册预览效果。

官方源码的注解很详细,并且很多都是中文

代码语言:jsx复制
{/*   简单使用  */}
<ImageViewer trigger={trigger} images={[image]} />

...
/**
* 触发图片预览的元素,可能是一个预览按钮,可能是一张缩略图,完全自定义
*/
trigger?: TNode | TNode<{
    open: () => void;
}>;

triiger是一个自定义的组件,使用用参数中的open来触发图片预览。

根据卡片效果示例,本案例设置相同图片来作为trigger就可以了。

嵌入card

card的组件本身就支持自定义封面内容

代码语言:jsx复制
    /**
    * 卡片封面图。值类型为字符串,会自动使用 `img` 标签输出封面图;也可以完全最定义封面图
    */
    cover?: TNode;

所以直接将图片放进去即可。

加入瀑布流容器

将上述的卡片再完善一下细节就可以加入容器了,瀑布流组件选择了第三方的react-masonry-component

代码语言:jsx复制
    <Masonry options={masonryOptions}>
      {pList &&
        pList.map((item, index) => {
          return <PictureCard key={`img_${index}`} {...item} />;
        })}
    </Masonry>

直接将图片列表放入即可。

无线滚动

需求:向下滚动自动加载新图片

直接翻译成react听懂的话就是监听滚动事件。所以很快得到如下代码:

代码语言:jsx复制
  //监听页面滚动事件
  window.onscroll = () => {
    // doSomeThing
  }

当你兴奋打开页面,在页面上滚动会发现,这个监听触发频率非常快,不一会浏览器就开始卡了。那么有没有一种让他只能单位时间内触发一次的方法呢?于是想到了定时器。

如果定时器没走完,再次调用就直接返回,这就变成了防抖。

如果定时器没走完,再次调用重置定时器,这就变成了节流。

当然完整的截流防抖实现起来比我所诉的更复杂,不过对于本案例的需求已经够用。

代码语言:jsx复制
    // 防抖
  const debounce = (fn: Function, delay: number) => {
    let timer: any = null;
    return function () {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        // @ts-ignore
        fn.apply(this, arguments);
      }, delay);
    };
  };

将原有方法作为参数来运行,就可以解决了。其中delay可以根据实际设置执行周期。

自动扩缩

需求:画面尺寸变化时,重新调整布局。

关于浏览器的东西都可以加入监听来处理,这里监听的事件就是resize

具体代码如下

代码语言:jsx复制
  const [_windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    const handleResize = () => {
      setWindowSize({ width: window.innerWidth, height: window.innerHeight });
    };

    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);

成果展示

多尺寸无限瀑布流多尺寸无限瀑布流

在最后

因为能力有限,没有手动实现瀑布流容器,不过在其他方面,也是收获蛮多,希望本文对你也有启发!

0 人点赞