ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

<list-view> 和 <waterfall-view> 详解

2026/8/20 11:12:56 拓冰建站 浏览量
<list-view> 和 <waterfall-view> 详解 在uni-app x中list-view和waterfall-view是专门为解决大数据量、长列表渲染卡顿/内存暴涨而设计的两个纯原生核心组件。与传统的 Web AppDOM 节点无限增加导致页面卡死不同这两个组件在 App 端直接映射为 Android 的RecyclerView和 iOS 的UICollectionView具备真正的原生 View 节点回收复用池。一、 传统scroll-viewvs 原生list-view区别对比项scroll-view(传统)list-view/waterfall-view底层实现纯滚动容器把所有节点都加载到内存中原生列表控件屏幕外节点自动销毁并回收复用内存开销随数据增加呈线性增长数千条数据必然卡死/爆内存内存始终保持在一个常数级仅保留屏幕可见项 缓冲项适用场景几条到几十条数据的短页面、局部滚动区域几百到数万条数据的长列表、下拉刷新/上拉加载列表、商城瀑布流二、list-view组件详解list-view用于实现垂直或水平方向的单列/多列普通长列表如聊天消息列表、医生列表、问诊历史、处方记录等。1. 核心配套组件list-item与type机制list-view的直接子节点必须是list-item。 其中最重要的属性是type(复用类型标识)复用原理当列表向上滚动时滑出屏幕顶部的list-item节点不会被销毁而是根据它的type值被放入原生复用池。当底部有新数据要滑入时系统直接从复用池拿出该节点仅更新里面的文本和图片数据。规则如果列表项的UI 样式完全一致给它们设置相同的type如type0。如果列表项有多种不同结构例如聊天页面左侧医生消息、右侧患者消息、中间系统提示必须给不同结构的子项设置不同的type如type1、type2。2. 吸顶效果支持 (sticky-header)无需任何 JS 计算滚动高度在list-view中搭配sticky-header或sticky-section组件即可实现纯原生的流畅分组标题吸顶效果。3. 常见属性与事件scroll-y/scroll-x开启垂直或水平滚动。refresher-enabled开启原生下拉刷新。refresherrefresh下拉刷新触发事件。scrolltolower滚动到底部触发上拉加载更多。show-scrollbar是否显示原生滚动条。bounces是否开启回弹效果iOS 原生弹性回弹。三、waterfall-view瀑布流组件详解waterfall-view专门用于参差不齐高度的卡片瀑布流布局如中医健康科普文章瀑布流、中药材/养生产品商城瀑布流。1. 解决的痛点在 Web 时代做瀑布流通常需要 JS 实时计算左右两列的高度或者用absolute绝对定位这会导致频繁触发 Web 重排Reflow极为耗性能。waterfall-view由 Native 原生 C 引擎AndroidStaggeredGridLayoutManager/ iOSUICollectionViewCompositionalLayout自动在底层计算卡片高矮零 JS 布局开销。2. 专属关键属性column-count瀑布流列数默认2列。column-gap列与列之间的横向间距。row-gap卡片与卡片之间的纵向间距。custom-header/custom-footer支持在瀑布流顶部或底部插入跨全宽的 Banner 或加载状态。四、.uvue实战代码示例1. 标准list-view列表代码示例template view classcontainer list-view classlist-container :scroll-ytrue :refresher-enabledtrue :refresher-triggeredisRefreshing refresherrefreshonRefresh scrolltoloweronLoadMore !-- 普通消息项 (type0) -- list-item v-for(item, index) in dataList :keyitem.id :type0 classlist-card image classavatar :srcitem.avatar/image view classinfo text classtitle{{ item.name }}/text text classdesc{{ item.diagResult }}/text /view /list-item !-- 底部加载更多提示 -- list-item :type99 classloading-item text classloading-text{{ isLoading ? 加载中... : 没有更多了 }}/text /list-item /list-view /view /template script setup uts type DoctorItem { id: string name: string avatar: string diagResult: string } const dataList refArrayDoctorItem([]) const isRefreshing ref(false) const isLoading ref(false) const onRefresh () { isRefreshing.value true // 模拟刷新数据 setTimeout(() { isRefreshing.value false }, 1000) } const onLoadMore () { if (isLoading.value) return isLoading.value true // 模拟加载下一页 } /script style scoped .container { flex: 1; } .list-container { flex: 1; } .list-card { flex-direction: row; padding: 15px; border-bottom-width: 1px; border-bottom-color: #eee; background-color: #ffffff; } .avatar { width: 50px; height: 50px; border-radius: 25px; } .info { margin-left: 12px; justify-content: center; } .title { font-size: 16px; font-weight: bold; } .desc { font-size: 14px; color: #666; margin-top: 4px; } /style2. 瀑布流waterfall-view代码示例template waterfall-view classwaterfall-container :column-count2 :column-gap10 :row-gap10 scrolltoloweronLoadMore !-- 瀑布流卡片 (type1) -- list-item v-forarticle in articleList :keyarticle.id :type1 classarticle-card image classcover :srcarticle.cover modewidthFix/image text classarticle-title{{ article.title }}/text text classauthor作者{{ article.author }}/text /list-item /waterfall-view /template五、 性能调优三大黄金法则必须使用list-item包裹并指定type 千万不要在list-view里直接放普通的view否则原生节点无法进行回收复用就失去了使用list-view的意义。不同布局结构的子项必须区分type 如果子项 A 是带图卡片type1子项 B 是纯文本标题type2绝不能将它们的type设为相同否则复用时会导致 UI 错乱。保持子项层级平坦list-item内部的节点嵌套层级越浅原生 View 布局计算速度就越快滚动流畅度越高。