推荐一个超好用的全栈通用瀑布流布局库 universal-waterfall-layout
在前端开发中,瀑布流布局(Masonry Layout)一直是一个让人又爱又恨的需求。爱它是因为它能极大提升图片类应用(如 Pinterest、小红书)的视觉体验和空间利用率;恨它是因为实现起来坑点满满——图片高度不固定、窗口缩放重排、框架兼容性问题等等。
今天给大家推荐一个最近发现的宝藏开源库:universal-waterfall-layout。
正如其名,不仅仅是给 Vue 用,也不仅仅是给 React 用,它是一个**通用(Universal)**的解决方案。
为什么选择它?
现在的市面上的瀑布流插件往往绑定特定框架,或者包体积过大。而 universal-waterfall-layout 有几个非常击中痛点的特性:
1. 🚀 全栈通用,一次学习
无论你是 Vue 3 爱好者,还是 React 拥趸,甚至是 原生 JS 的死忠粉,这个库都能无缝支持。它的核心逻辑是用原生 TypeScript 编写的,零依赖,仅仅在核心之上封装了轻量级的 Vue 和 React 组件适配层。
2. ⚡️ 内置"刚需"功能
很多瀑布流插件只管布局,不管体验。但这个库在 v1.0.3 版本中贴心地加入了很多实战刚需功能:
- 骨架屏 (Skeleton Loading): 数据还没回来?直接通过 props 开启加载状态,自带脉冲动画的骨架屏,拒绝白屏。
-
空状态 (Empty State): 列表为空时自动显示占位提示,不再需要自己写
v-if/v-else。 - 图片懒加载 (Lazy Load): 内置原生图片懒加载支持,性能直接拉满,不需要再引入额外的 lazyload 库。
3. 📐 两种核心布局策略
它不仅仅是简单的“排列”,还提供了两种最常用的响应式策略:
-
固定列宽 (Fixed Column Width): 指定每列
250px,容器会自动计算能放下几列,并自动居中。适合大屏展示。 - 固定列数 (Fixed Column Count): 指定“我要 3 列”,无论屏幕多大,宽度都会自动拉伸填满。适合移动端 H5。
快速上手
安装
非常简单,体积也很小:
npm install universal-waterfall-layout
# 或者
pnpm add universal-waterfall-layout
via Vue 3
在 Vue 中使用非常丝滑,你可以直接利用 slot 来自定义加载中和空状态的 UI:
<template>
<Waterfall
:gap="20"
:columnWidth="250"
:loading="isLoading"
:lazyload="true"
>
<!-- 数据列表 -->
<div v-for="item in items" :key="item.id" class="card">
<img :src="item.image" alt="" />
<p>{{ item.title }}</p>
</div>
<!-- 自定义加载骨架 -->
<template #loading>
<div class="my-skeleton">正在加载精彩内容...</div>
</template>
<!-- 自定义空状态 -->
<template #empty>
<div class="empty-box">暂无相关数据</div>
</template>
</Waterfall>
</template>
<script setup>
import { Waterfall } from 'universal-waterfall-layout/vue';
import { ref } from 'vue';
const isLoading = ref(true);
const items = ref([]);
// 模拟请求
setTimeout(() => {
items.value = [{/*...*/}, {/*...*/}];
isLoading.value = false;
}, 1000);
</script>
via React
React 版本同样拥有优秀的类型提示(TypeScript Friendly):
import { Waterfall } from 'universal-waterfall-layout/react';
const MyGallery = ({ data, loading }) => {
return (
<Waterfall
gap={15}
columnCount={3} // 移动端常用:固定3列
loading={loading}
lazyload={true}
loadingComponent={<div>Loading Skeleton...</div>}
emptyComponent={<div>Nothing here yet!</div>}
>
{data.map(item => (
<div key={item.id} className="card">
<img src={item.url} />
</div>
))}
</Waterfall>
);
};
via Vanilla JS (原生 HTML)
如果你不使用任何框架,或者在传统的 HTML 页面中使用,也完全没问题。核心库提供了直接操作 DOM 的能力:
<div id="waterfall-container">
<div class="item"><img src="..." /></div>
<div class="item"><img src="..." /></div>
<!-- ... -->
</div>
<script type="module">
import { WaterFallCore } from 'universal-waterfall-layout';
const container = document.getElementById('waterfall-container');
const waterfall = new WaterFallCore({
container: container, // 必填:容器 DOM 元素
gap: 15, // 间距
columnWidth: 220, // 固定列宽策略
lazyload: true // 开启懒加载
});
// 如果后续通过 JS 动态添加了元素,可以手动触发布局更新
// waterfall.updateItems();
// waterfall.layout();
</script>
结语
在造轮子泛滥的今天,找到一个克制且好用的库并不容易。universal-waterfall-layout 没有过度封装,但把最核心的布局算法、响应式处理和加载体验做得非常扎实。
如果你正在开发图片流、商品墙或者作品集展示页面,强烈推荐试一试!
🔗 NPM 地址: universal-waterfall-layout