真瀑布流必须服务端宽高预估+客户端尺寸预加载+二维数组分发+手动同步scroll-view高度与columnheights状态。取模分列是假瀑布流,因不考虑图片真实高度;scroll-view需用calc减去导航栏高度,禁用absolute;每次数据刷新必须显式重置columnheights=[0,0]。

不能用 column-count 或 display: grid 实现真瀑布流,三端(尤其微信小程序)会忽略、降级或不重排,首屏错位、触底监听失效是必然结果。
为什么取模分列(index % 2)看起来像瀑布流,实际是假的
这种写法把第 0、2、4… 项塞左列,1、3、5… 塞右列,完全不考虑每张图真实高度。一旦图片宽高比差异大(比如 1:1 和 4:5 混排),两列高度迅速失衡——左列堆到屏幕外,右列还空着半截。这不是样式问题,是分配逻辑没跟上渲染节奏。
- 服务端返回的
width和height字段必须参与预估:用height: calc(100% * item.height / item.width)设内联样式,防初始塌陷 - 没服务端宽高时,用
uni.getImageInfo({ src })并发 ≤ 3 预加载,拿到尺寸再插入,比等@load后查 DOM 快且稳 - 分发逻辑必须在
computed或watch中完成二维数组构建(如columns = [[], []]),不能在模板v-for里实时算
scroll-view 高度和滚动监听必须手动对齐真实内容高度
很多人设了 height: 100vh 就以为万事大吉,结果 iOS 微信里滚不到底、安卓留白、H5 触底失效。根本原因是:scroll-view 不会自动感知子项高度变化,更不会重算可滚动区域。
基于“创意扇形排列卡片画廊”制作的前端特效源码,包含扇形卡片、旋转展开、层级聚焦、键盘切换,打开 index.html 即可直接查看效果,可替换标题、颜色和图形元素复用。 下载包已经整理好特效舞台、样式变量、动画规则和必要脚本,适合用于学习当前效果的实现方式,也方便替换文字、颜色、图形或图片后直接复用。
- 高度必须用
calc(100vh - 100rpx)这类表达式(减去导航栏、TabBar 等实际占用),vh在小程序里直接无效 - 禁用子元素
position: absolute—— iOS 微信中会导致scrolltolower完全不触发 - 图片加载后高度变更,必须调用
uni.createSelectorQuery()主动获取最新内容高度,再setData更新scroll-view的scroll-top或触发重绘
分类切换或刷新时,columnHeights 数组必须同步重置
只清空数据源 list 和分列数组 columns,却忘了重置 columnHeights = [0, 0],新数据就会按旧高度叠加——第一张图直接掉出可视区,或者整列空白。这个状态不是“隐式清零”,必须显式赋值。
- 每次
list替换(如分类 tab 切换、下拉刷新),都要同步执行this.columnHeights = [0, 0] - 如果用了封装组件(如
<hy-waterfall></hy-waterfall>),确认它内部是否自动重置;没文档说明的,宁可自己包一层 wrapper 手动控制 - 调试时直接
console.log(this.columnHeights),比盯着 UI 猜“为什么首屏没图”快得多
真瀑布流的稳定性和可维护性,不取决于 flex 写得多漂亮,而取决于高度状态是否被准确捕获、及时更新、干净重置。图片异步加载、小程序渲染机制、scroll-view 行为边界,这三者叠加后,任何一步松动都会导致整列错位或滚动失效。










