鸿蒙平台 uni-app x scroll-view 嵌套滚动冲突解决方
在鸿蒙平台使用 uni-app x 开发时,scroll-view 是聊天记录、商品列表、Tab 切换、横向轮播和下拉刷新等场景的常用容器。鸿蒙从 4.61 版本开始支持该组件。它看起来简单,但嵌套滚动冲突、下拉刷新元素位置、废弃属性等问题在鸿蒙上需要单独适配。一、scroll-view 核心能力
scroll-view 支持横向滚动、竖向滚动、下拉刷新和嵌套滚动。滚动方向由 direction 控制:none 禁止滚动,all 横竖同时可滚动,horizontal 横向,vertical 竖向。滚动位置、阈值、回弹效果和下拉刷新等通过属性配置。事件对象为 UniScrollEvent,可以通过 @scroll、@scrollend 等获取滚动位置。基础竖向滚动、横向滚动、下拉刷新、上拉加载、滚动到指定位置等场景,都是围绕这些属性组合实现。其中上拉加载监听 @scrolltolower,配合 :lower-threshold='100' 设置触发距离;滚动到指定位置可用 :scroll-top 或 scroll-into-view,配合 :scroll-with-animation='true' 实现动画。
二、鸿蒙平台专属适配
自定义下拉刷新元素的位置在鸿蒙上与其他平台不同。Android 和 iOS 平台,自定义下拉刷新元素不能放在 scroll-view 的首个子元素位置;鸿蒙平台则要放在最后一个子元素的位置,否则顶部可能出现空白区域。
<scroll-view refresher-default-style='none' :refresher-enabled='true'>
<view v-for='i in 20'>...</view>
<view slot='refresher'>
<text>下拉刷新</text>
</view>
</scroll-view>
嵌套滚动冲突可以通过嵌套模式解决。外层 scroll-view 设置 type='nested',子节点只能放 nested-scroll-header 和 nested-scroll-body;内层 scroll-view 设置 associative-container='nested-scroll-view'。
<scroll-view type='nested'>
<nested-scroll-header>
<view>头部</view>
</nested-scroll-header>
<nested-scroll-body>
<scroll-view associative-container='nested-scroll-view'>
<view>内容</view>
</scroll-view>
</nested-scroll-body>
</scroll-view>
嵌套滚动策略为:向下滚动(手指上滑)先滚外层,再滚内层;向上滚动(手指下滑)先滚内层,再滚外层。
除了嵌套模式,鸿蒙平台还支持嵌套滚动协商。通过 nested-scroll-child='listview' 关联子元素,监听 @startnestedscroll、@nestedprescroll、@stopnestedscroll 三个事件。@startnestedscroll 在子元素开始滚动时触发,return true 建立协商;@nestedprescroll 在子元素滚动时通过 consumed(x,y) 告知消耗量;@stopnestedscroll 在子元素滚动结束时触发。
<scroll-view nested-scroll-child='listview'
@startnestedscroll='onStartNestedScroll'
@nestedprescroll='onNestedPreScroll'
@stopnestedscroll='onStopNestedScroll'>
<list-view id='listview' custom-nested-scroll='true'>
...
</list-view>
</scroll-view>
与鸿蒙原生 Scroll 组件对比,原生写法如下:
Scroll() {
Column() {
ForEach(this.list, (item: string) => {
Text(item).fontSize(16).padding(15)
})
}
}
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.On)
uni-app x 的 scroll-view 功能更丰富。下拉刷新、嵌套滚动、scroll-into-view 这些功能在原生 Scroll 上都需要自己实现。
三、踩坑与总结
不要使用已废弃的 scroll-x 和 scroll-y 属性,改用 direction 属性。例如竖向滚动写 direction='vertical',横向滚动写 direction='horizontal'。在鸿蒙平台开发时,重点检查自定义下拉刷新元素是否放在末尾、嵌套滚动是否按 nested 模式配置,以及是否误用了废弃属性。掌握这些差异后,聊天列表、商品流、Tab 切换等滚动场景可以更稳定地落地。
Re: 鸿蒙平台 uni-app x scroll-view 嵌套滚动冲突解决方
感谢分享,这篇整理得很清楚。鸿蒙上自定义下拉刷新元素要放在最后一个子元素位置,不然顶部可能出现空白,这个点很容易踩坑,之前真没特别注意。嵌套滚动用 type 为 nested,再配合 nested-scroll-header 和 nested-scroll-body,内层设置 associative-container,这个结构比直接硬调滚动冲突清晰多了。协商模式那几个事件看起来适合更复杂的联动场景。废弃的 scroll-x、scroll-y 改成 direction 也很实用,后面做聊天列表和商品流时会重点检查这几项。总结的排查点很到位,少走弯路。Re: 鸿蒙平台 uni-app x scroll-view 嵌套滚动冲突解决方
感谢分享,这篇把鸿蒙上 scroll-view 的几个关键差异讲得很清楚。之前只知道要改用 direction,没想到自定义下拉刷新元素在鸿蒙要放到最后一个子元素,和 Android、iOS 相反,确实容易导致顶部空白。嵌套滚动那部分也很实用,外层 type 设为 nested,里面只能放 nested-scroll-header 和 nested-scroll-body,内层再设 associative-container 为 nested-scroll-view,这个结构以后排查冲突就有方向了。还有 nested-scroll-child 配合三个事件做协商,虽然暂时没用上,但先记下了。最后废弃 scroll-x、scroll-y 改用 direction 这点也很有帮助,后面做聊天列表和商品流会重点检查这些点。收藏了。Re: 鸿蒙平台 uni-app x scroll-view 嵌套滚动冲突解决方
感谢分享,整理得很清楚。之前确实容易忽略鸿蒙上自定义下拉刷新元素要放在最后一个子元素这个差异,和 Android、iOS 的放置位置不一样,不注意顶部就会多出空白。嵌套滚动两种方案也讲得比较明白:nested 模式适合外层固定 header、body 包内容的场景,协商模式更适合 listview 这类子元素主动上报消耗量的情况。顺便确认一下,@nestedprescroll 里的 consumed(x,y) 就是告诉外层本次子元素消耗了多少滚动量,剩余部分再交给外层处理,对吧?另外废弃属性这点也很实用,统一用 direction 确实能省掉不少排查成本。Re: 鸿蒙平台 uni-app x scroll-view 嵌套滚动冲突解决方
感谢分享,正好最近在鸿蒙上折腾 uni-app x 的滚动列表,这些点很实用。之前我也遇到过自定义下拉刷新顶部空白,还以为是布局问题,原来是鸿蒙要把 refresher 放在最后一个子元素位置,这个差异确实容易踩。废弃的 scroll-x 和 scroll-y 也经常在旧示例里看到,改用 direction 后清晰多了。嵌套滚动按 type 为 nested、配合 nested-scroll-header 和 nested-scroll-body,再给内层设置 associative-container 这个思路很明确;协商那套事件还没实际用过,回头按你提到的 startnestedscroll、nestedprescroll、stopnestedscroll 试一下。最后总结的下拉刷新位置、嵌套配置、废弃属性这几个检查项很到位,基本覆盖了鸿蒙上容易出问题的地方。感谢整理。
页:
[1]