最稳的双列布局方案是父容器设display: flex+flex-wrap: wrap,子项设flex: 0 0 48%或固定宽如width: 344rpx,兼容全端且避免小程序错位、滚动失效等问题。

uni-app 用 flex 实现商品双列布局,关键在父容器设 flex-wrap: wrap
直接说结论:不用 grid、不用 column-count、不推荐 u-list 套娃嵌套——最稳的双列方案就是外层 view 设 display: flex + flex-wrap: wrap,子项设固定宽度(如 width: 344rpx)或 flex: 0 0 48%。这样既兼容 H5、小程序、App 全端,又不会出现 column-count 在 iOS 微信里错位、u-list 内部嵌套导致滚动失效等问题。
常见错误现象:flex-direction: column 搞两列(结果是上下堆叠)、子项没设 flex-shrink: 0 导致在窄屏被压缩变形、用 justify-content: space-between 但最后一行只剩一个 item 时左右留白过大。
- 子项必须设
flex: 0 0 48%或明确width,不能只靠flex: 1—— 否则多列下会拉伸错乱 - 建议用
rpx单位写宽高,比如width: 344rpx; height: 516rpx,避免 iPhone SE 等小屏溢出 - 如果需等高对齐,别依赖
align-items: stretch(部分小程序不生效),改用min-height+ 内容区域flex-direction: column控制
为什么不用 column-count: 2?它在微信小程序里会漏掉首项
column-count: 2 看似简洁,但 uni-app 编译到微信小程序时,底层用的是 scroll-view + view 模拟,而微信原生对 CSS 多列支持极弱:首项常被截断、break-inside: avoid 失效、图片加载后列高重排错乱。实测在 iOS 微信 8.0.54+ 仍存在首项不渲染问题,且无法通过 key 强刷修复。
对比来看,flex 方案完全由 uni-app 渲染层控制,DOM 结构扁平,v-for 数据更新后重排稳定;而 column-count 是浏览器/WebView 引擎自行分列,uni-app 无法干预其计算逻辑。
- 如果你已在用
column-count且只跑 H5,可保留;但只要目标含小程序,立刻换 flex - 别信“加
transform: translateZ(0)就能触发硬件加速修复”——这在小程序里无效 - uni-app 官方文档也已将
column-count标为「仅 H5 支持」
使用 u-list 实现双列时,height 必须动态计算,否则触底事件不触发
很多人抄 uview-plus 的示例代码,直接写死 :height="500",结果 @scrolltolower 死活不执行。根本原因是:u-list 的触底判断依赖真实滚动高度,而该高度 = 父容器 height - u-list 自身 padding/margin。若 height 设小了,内容还没撑满就“到底”;设大了,永远达不到阈值。
正确做法是在 onMounted 中动态算:uni.getSystemInfoSync().windowHeight 减去顶部导航栏、tabBar、其他固定模块高度,再转成 rpx 或 px(注意 uni-app 的 rpx 是以 750rpx=屏幕宽为基准,不是 375px)。
- 别用
uni.createSelectorQuery()查父容器高——异步时机难控,容易错过首次 scrolltolower - u-list 内部子项必须用
u-list-item包裹,直接放view会导致高度计算异常 - 若列表数据少于一屏,
scrolltolower永远不会触发,需额外加v-if="goodsList.length >= 10"判断是否显示“加载更多”提示
双列布局下图片宽高比失真?优先用 image 组件的 mode="aspectFill"
uni-app 的 image 组件在不同端对 width/height 的解析不一致:H5 下按 CSS 盒模型,小程序里可能按原始尺寸缩放。若你用 view 包 image 并设 overflow: hidden,但没指定 image 的 mode,就会出现拉伸、留白、裁剪偏移。
推荐组合:<image :src="item.image" mode="aspectFill" style="width: 100%; height: 344rpx;"></image>。其中 aspectFill 保证填满且不形变,height 固定让每张图高度一致,便于 flex 子项对齐。
- 别用
scaleToFill—— 会强制拉伸变形 - 别在
image上设border-radius—— 部分安卓机圆角失效,应在外层view上设 - 如果后端返回图尺寸差异极大(如 100×100 和 2000×3000),先用云函数统一裁成 750×750 再下发,比前端硬处理更可靠
实际中最容易被忽略的点:双列 flex 布局下,每个子项的 margin-bottom 必须设为偶数 rpx(如 20rpx),否则在 iPhone 14 Pro 等高 DPR 屏幕上,两列底部对不齐——因为半像素渲染会被四舍五入,导致视觉错位。











