Skip to content

ImageWaterfall 图片瀑布流 小程序

微信小程序通用图片瀑布流组件 —— 预留高度防抖动(零 CLS)+ 高端骨架屏 + 淡入 + 多列分配 + 触底加载。不依赖任何第三方库,纯原生 <image> 实现,CSS 变量即可主题化。

GitHub  npm  repo

为什么没有在线演示?

这是微信小程序组件(基于 scroll-view / 原生 image),无法在网页中直接运行。下面提供真机录屏扫码体验,效果一目了然。

效果演示

瀑布流真机演示

真机演示:骨架屏 → 淡入 → 触底加载

📱 扫码体验微信扫码体验小程序微信扫一扫,在「珊瑚打码」小程序中体验瀑布流效果

特性

  • 零布局抖动:图片返回前用「确定性宽高比」预留高度,加载前后高度一致,彻底消除 CLS 跳动
  • 高端骨架屏:底色 + 斜向流光 + 中心微光,图片加载完成后平滑淡入
  • 多列瀑布流:任意列数(默认 2 列),按「最矮列优先」分配,排布均衡
  • 触底加载 & 切换重建:内置无限滚动事件;切换分类/搜索时整体原子替换并自动回顶
  • 加载失败回退:可配置回退字段(如缩略图),失败自动降级
  • 主题化:CSS 自定义属性控制圆角、间距、骨架配色、标题样式,适配深色/浅色

安装

方式一:npm(推荐)

bash
npm i sk-image-waterfall

安装后在微信开发者工具执行「工具 → 构建 npm」,然后在页面/组件的 .json 注册:

json
{
  "usingComponents": {
    "image-waterfall": "sk-image-waterfall/image-waterfall/image-waterfall"
  }
}

方式二:手动拷贝

将仓库的 image-waterfall/ 目录拷贝到项目 components/ 下并注册:

json
{
  "usingComponents": {
    "image-waterfall": "/components/image-waterfall/image-waterfall"
  }
}

容器高度

组件根节点是 scroll-view,高度取父容器。请给它一个确定高度(如 flex 纵向布局中设 flex: 1; min-height: 0)。

快速使用

html
<view class="page">
  <image-waterfall
    class="flow"
    list="{{list}}"
    reset-token="{{token}}"
    image-key="url"
    title-key="name"
    bind:itemtap="onItemTap"
    bind:loadmore="onLoadMore"
  >
    <!-- 默认插槽渲染在列表底部:放 loading / 空态 / 没有更多 -->
    <view wx:if="{{loading}}" class="tip">加载中…</view>
  </image-waterfall>
</view>
css
.page { height: 100vh; display: flex; flex-direction: column; }
.flow { flex: 1; min-height: 0; }
js
Page({
  data: { list: [], token: 0, loading: false },

  onLoad() { this.reload() },

  async reload() {
    const data = await fetchData(/* page 1 */)
    // 切换分类/搜索:更新数据并「改变 reset-token」触发重建+回顶
    this.setData({ list: data, token: this.data.token + 1 })
  },

  onLoadMore() {
    // 加载更多:往 list 尾部追加,组件自动增量渲染
    fetchData(/* next page */).then((more) => {
      this.setData({ list: this.data.list.concat(more) })
    })
  },

  onItemTap(e) {
    const item = e.detail.item // 原始数据项
  }
})

约定(重要)

  • 加载更多 → 往 list 尾部 concat 新数据,reset-token 保持不变,组件只渲染新增部分
  • 切换分类 / 搜索 → 更新 list 的同时改变 reset-token(如 +1),组件整体重建并回到顶部

API

Props

属性说明类型默认值
list数据源,元素为对象或图片 URL 字符串Array[]
columns列数Number2
gap间距(rpx),用于外边距/列间距/卡片下边距Number20
image-key取图片 URL 的字段名(元素为字符串时忽略)String'src'
fallback-key图片加载失败时回退的字段名String'thumb'
title-key标题字段名String'title'
show-title是否展示标题Booleantrue
ratios预留宽高比集合,如 [0.72, 1, 1.3],越多档错落越丰富Array内置
reset-token值变化即整体重建并回到顶部any0
lower-threshold触底触发距离(px)Number120

Events

事件名说明event.detail
itemtap点击某张图{ item, index }item 为原始数据项
loadmore滚动触底(父组件取下一页并追加到 list-

Slots

插槽名说明
default渲染在瀑布流底部(滚动容器内),放「加载中 / 空态 / 没有更多」提示

主题(CSS 变量)

父级给组件设置即可穿透生效:

css
.flow {
  --wf-radius: 16rpx;
  --wf-card-bg: #0f1526;
  --wf-skeleton-base: #121a2e;
  --wf-skeleton-shine: rgba(255, 255, 255, 0.07);
  --wf-fade: 0.45s;
  --wf-title-color: #cbd5e1;
}
变量默认值说明
--wf-gapgap 属性间距
--wf-radius16rpx卡片圆角
--wf-card-bgtransparent卡片背景
--wf-card-border卡片边框
--wf-skeleton-base#edf0f5骨架底色
--wf-skeleton-shinergba(255,255,255,.55)骨架流光色
--wf-skeleton-glowrgba(0,0,0,.05)骨架中心微光
--wf-fade.45s图片淡入时长
--wf-title-color#333标题颜色
--wf-title-size24rpx标题字号

源码与反馈

Released under the MIT License.