A lightweight, cross-framework waterfall layout library.
npm install universal-waterfall-layoutEnglish | 中文
一个轻量级、高性能的瀑布流布局库,支持 Vue 3、React 和 原生 JS。
- 🚀 框架无关: 核心逻辑使用原生 TypeScript 编写。
- ⚡ 轻量级: 零依赖(核心部分)。
- 🎨 响应式: 自动处理窗口大小调整。
- 📐 灵活布局: 同时支持 固定列宽(居中布局)和 固定列数(流式宽度)。
- 🖼 图片加载: 即使图片尺寸动态变化也能保持稳健布局。
- 💤 懒加载: 内置支持原生图片懒加载。
- ⏳ 状态管理: 内置加载中(骨架屏)和空状态支持。
- 🚀 虚拟列表: 支持万级数据渲染,基于 $O(\log N)$ 算法实现高性能检索。
- ⚓ 滚动锚定: 解决动态高度撑开导致的布局跳动,保持丝滑滑动体验。
- 🔌 可扩展: 易于扩展自定义动画。
``bash`
npm install universal-waterfall-layoutor
pnpm add universal-waterfall-layout
从 /vue 子路径导入 Waterfall 组件。
`vue
:columnWidth="250"
:loading="isLoading"
:lazyload="true"
>
...
加载中...
暂无数据
...
{{ item.title }} - {{ index }}
:items="massiveData"
:height="800"
:gap="20"
:columnWidth="200"
>
`
| 属性 | 类型 | 默认值 | 描述 |
|------|------|---------|-------------|
| gap | Number | 10 | 元素之间的间距(像素)。 |columnWidth
| | Number | - | 策略 1: 每列的固定宽度。容器将会居中显示。 |columnCount
| | Number | - | 策略 2: 固定的列数。宽度是流式的(自适应)。 |items
| | Array | [] | 可选:传入数据数组以便在变化时触发重新布局。 |loading
| | Boolean | false | 如果为真,显示加载骨架屏。 |lazyload
| | Boolean | false | 开启原生图片懒加载。 |reachBottomDistance
| | Number | 50 | 触底事件触发阈值(像素)。 |virtual
| | Boolean | false | 开启虚拟列表模式(高性能处理大数据量)。 |height
| | String \| Number | - | 设置容器高度,开启内部滚动。 |estimateItemHeight
| | Number | 300 | 虚拟列表预估高度。 |
| 事件名 | 描述 |
|-------|-------------|
| scroll-reach-bottom | 当滚动触底时触发。可用于无限滚动加载。 |
| 插槽 | 描述 |
|------|-------------|
| default | 主要内容项(非虚拟模式)。 |item
| | 开启虚拟模式后的单项渲染插槽。接受 { item, index } 参数。 |loading
| | 加载状态的自定义内容。 |empty
| | 空状态的自定义内容。 |
从 /react 子路径导入 Waterfall 组件。
`tsx
import React from 'react';
import { Waterfall } from 'universal-waterfall-layout/react';
const App = () => {
return (
// 策略 1: 固定宽度 (居中)
columnWidth={250}
loading={false}
lazyload={true}
loadingComponent={
// 策略 2: 固定列数 (流式)
{children}
// 策略 3: 虚拟列表模式
items={massiveItems}
height={800}
gap={20}
columnWidth={200}
renderItem={(item, index) => (
$3
| 属性 | 类型 | 默认值 | 描述 |
|------|------|---------|-------------|
|
gap | number | 10 | 元素之间的间距(像素)。 |
| columnWidth | number | - | 每列的固定宽度。 |
| columnCount | number | - | 固定的列数。 |
| loading | boolean | false | 如果为真,显示加载骨架屏。 |
| lazyload | boolean | false | 开启原生图片懒加载。 |
| loadingComponent | ReactNode | - | 自定义加载状态组件。 |
| emptyComponent | ReactNode | - | 自定义空状态组件。 |
| onReachBottom | () => void | - | 滚动触底回调函数。 |
| reachBottomDistance | number | 50 | 触发触底事件的距离阈值(像素)。 |
| virtual | boolean | false | 是否开启虚拟列表模式。 |
| items | any[] | [] | 虚拟模式下必填:完整的数据数组。 |
| renderItem | (item, index) => ReactNode | - | 虚拟模式下必填:单项渲染函数。 |
| height | string \| number | - | 容器高度,设置此项后开启内部滚动。 |
| estimateItemHeight | number | 300 | 虚拟模式下的预估高度。 |原生 JS / 核心库使用方法
如果你不想使用框架:
`javascript
import { WaterFallCore } from 'universal-waterfall-layout';const container = document.getElementById('my-container');
const waterfall = new WaterFallCore({
container: container,
gap: 15,
columnWidth: 220,
lazyload: true,
onLayout: () => {
console.log('布局已更新');
}
});
// 销毁
waterfall.destroy();
`API 选项
| 选项 | 类型 | 默认值 | 描述 |
|--------|------|---------|-------------|
|
container | HTMLElement | 必填 | 容器元素。 |
| gap | number | 0 | 间距大小(px)。 |
| columnWidth | number | - | 选项 A: 固定列宽。如果设置了此项,columnCount 将被忽略。 |
| columnCount | number | - | 选项 B: 固定列数。宽度动态计算。 |
| itemSelector | string | 直接子元素 | 这里的 CSS 选择器用于选择子项。 |
| lazyload | boolean | false | 开启原生图片懒加载。 |
| onLayout | function | - | 布局计算完成后的回调。 |
| onReachBottom | function | - | 滚动触底回调函数。 |
| reachBottomDistance | number | 50 | 触底阈值(px)。 |
| virtual | boolean | false | 是否开启虚拟滚动模式。 |
| onRenderChange | (start, end) => void | - | 可见区域范围变化时的回调(仅限虚拟模式)。 |
| viewport | HTMLElement \| Window | window | 指定滚动视口容器。 |
| estimateItemHeight | number | 300 | 虚拟列表项的预估高度。 |
| itemCount | number | 0 | 总数据项数量(虚拟模式必填)。 |开发
1. 安装依赖:
npm install
2. 构建库: npm run build`