真瀑布流必须用js动态分配图片到最短列并实时维护高度数组,核心是初始化columnheights=[0,0],每张图加载后查真实高度,找到最小值索引并更新对应列高;需避开scroll-view样式坑,分类切换时同步重置高度数组和分列二维数组。

不能靠 column-count 或 display: grid 实现真瀑布流,尤其在小程序端会被忽略或降级;必须用 JS 动态分发图片到最短列,并实时维护高度数组。
怎么用 JS 动态分配图片到最短列
核心是维护一个列高数组,比如两列就用 columnHeights = [0, 0],每次拿到一张图的真实高度后,找最小值索引,把该项 push 进对应列并更新该列高度。
- 别按奇偶下标硬分——那样只是“交替排列”,不是瀑布流,视觉上会明显左高右低或一列堆满再堆另一列
- 高度不能靠 DOM 初始渲染值,得等
@load触发后用uni.createSelectorQuery()查boundingClientRect获取真实高度 - 服务端返回
width/height字段最稳;没条件就用uni.getImageInfo预加载(并发 ≤ 3),避免 onLoad 后再查 DOM 延迟 - 分发逻辑别写在
v-for里,应在computed或watch中提前构建二维数组(如columns = [[], []])
scroll-view 容器必须避开的三个坑
scroll-view 是目前 uni-app 唯一能稳定监听 scrolltolower 的容器,但它对样式极其敏感,尤其在小程序里。
- 禁用子元素
position: absolute——iOS 微信里会丢失scrolltolower触发,安卓也可能错位 - 不能设
height: 100vh——小程序不识别vh单位,得用height: calc(100vh - 100rpx)(减掉导航栏、TabBar 等实际占用高度) - 子项高度变化后,
scroll-view不会自动重算滚动高度,必须手动调用uni.createSelectorQuery()获取最新高度,再setData更新,否则底部留白或触发不了下一页
分类切换时如何正确重置瀑布流状态
左侧菜单切换分类,右侧数据重置,但很多人只清了 list 和 columnList,忘了重置 columnHeights = [0, 0] 和二维分列数组(如 [[ ], [ ]])。
- 结果新数据还往旧高度上叠,第一张图直接掉出屏幕,或首屏空白
- 每次分类变更,必须同步重置高度数组 + 分列二维数组
- 如果用了作用域插槽(如
<hy-waterfall></hy-waterfall>),确认其内部是否自动重置高度状态;没文档说明的,宁可自己封装一层 wrapper 手动控制 - 调试时打印
columnHeights变化,比看 UI 更快定位“为什么第一张图不见了”
真瀑布流的关键不在布局样式,而在高度状态是否实时、准确、可重置——图片加载异步性、小程序渲染机制、scroll-view 的行为边界,三者缺一不可。











