# scroll-view
Component Type:UniScrollViewElement
可滚动视图容器
# # Attributes
name | type | default | description |
---|---|---|---|
scroll-x | boolean | false | 允许横向滚动,不支持同时设置scroll-y属性为true,同时设置true时scroll-y生效 |
scroll-y | boolean | true | 允许纵向滚动,不支持同时设置scroll-x属性为true,同时设置true时scroll-y生效 |
rebound | boolean | true | 控制是否回弹效果 |
upper-threshold | number | 50 | 距顶部/左边多远时(单位px),触发 scrolltoupper 事件 |
lower-threshold | number | 50 | 距底部/右边多远时(单位px),触发 scrolltolower 事件 |
scroll-top | number | 0 | 设置竖向滚动条位置 |
scroll-left | number | 0 | 设置横向滚动条位置 |
scroll-into-view | string.IDString | - | 值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素 |
scroll-with-animation | boolean | false | 是否在设置滚动条位置时使用滚动动画,设置false没有滚动动画 |
refresher-enabled | boolean | false | 开启下拉刷新,暂时不支持scroll-x = true横向刷新 |
refresher-threshold | number | 45 | 设置下拉刷新阈值 |
refresher-max-drag-distance | number | - | 设置下拉最大拖拽距离(单位px),默认是下拉刷新控件高度的2.5倍 |
refresher-default-style | string | black | 设置下拉刷新默认样式,支持设置 black | white | none, none 表示不使用默认样式 refresher-default-style |
refresher-background | string.ColorString | #FFF | 设置下拉刷新区域背景颜色 |
refresher-triggered | boolean | false | 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发 |
show-scrollbar | boolean | true | 控制是否出现滚动条 |
custom-nested-scroll | boolean | false | 子元素是否开启嵌套滚动 将滚动事件与父元素协商处理 |
nested-scroll-child | string.IDString | 嵌套滚动子元素的id属性,不支持ref,scroll-view惯性滚动时会让对应id元素视图进行滚动,子元素滚动时会触发scroll-view的nestedprescroll事件,嵌套子元素需要设置custom-nested-scroll = true | |
@refresherpulling | (event: RefresherEvent ) => void | - | 下拉刷新控件被下拉 |
@refresherrefresh | (event: RefresherEvent ) => void | - | 下拉刷新被触发 |
@refresherrestore | (event: RefresherEvent ) => void | - | 下拉刷新被复位 |
@refresherabort | (event: RefresherEvent ) => void | - | 下拉刷新被中止 |
@scrolltoupper | (event: ScrollToUpperEvent ) => void | - | 滚动到顶部/左边,会触发 scrolltoupper 事件 |
@scrolltolower | (event: ScrollToLowerEvent ) => void | - | 滚动到底部/右边,会触发 scrolltolower 事件 |
@scroll | (event: ScrollEvent ) => void | - | 滚动时触发,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY} |
@startnestedscroll | (event: StartNestedScrollEvent ) => Boolean | - | 子元素开始滚动时触发, return ture表示与子元素开启滚动协商 默认return false! event = {node} |
@nestedprescroll | (event: NestedPreScrollEvent ) => void | - | 子元素滚动时触发,可执行event.consumed(x,y)告知子元素deltaX、deltaY各消耗多少。子元素将执行差值后的deltaX、deltaY滚动距离。不执行consumed(x,y)则表示父元素不消耗deltaX、deltaY。event = {deltaX, deltaY} |
@stopnestedscroll | (event: Event ) => void | - | 子元素滚动结束或意外终止时触发 |
# # refresher-default-style
name | description |
---|---|
black | 深颜色雪花样式 |
white | 浅白色雪花样式 |
none | 不使用默认样式 |
# # refresher-default-style Compatibility
Android version | Android uni-app | Android uni-app-x | iOS version | iOS uni-app | iOS uni-app-x | |
---|---|---|---|---|---|---|
black | 5.0 | x | 3.9+ | - | - | - |
white | 5.0 | x | 3.9+ | - | - | - |
none | 5.0 | x | 3.9+ | - | - | - |
# # Event
# # RefresherEvent
# # RefresherEvent Values
name | type | required | default | description |
---|---|---|---|---|
detail | RefresherEventDetail | YES | - | - |
type | string | YES | - | 事件类型 |
target | Element | YES | - | 触发事件的组件 |
currentTarget | Element | YES | - | 当前组件 |
timeStamp | number | YES | - | 事件发生时的时间戳 |
# # RefresherEventDetail Values
name | type | optinal | default | description |
---|---|---|---|---|
dy | number | YES | - | - |
# # RefresherEvent Methods
name | type | required | default | description |
---|---|---|---|---|
stopPropagation | () => void | YES | - | 阻止当前事件的进一步传播 |
preventDefault | () => void | YES | - | 阻止当前事件的默认行为 |
# # ScrollToUpperEvent
# # ScrollToUpperEvent Values
name | type | required | default | description |
---|---|---|---|---|
detail | ScrollToUpperEventDetail | YES | - | - |
type | string | YES | - | 事件类型 |
target | Element | YES | - | 触发事件的组件 |
currentTarget | Element | YES | - | 当前组件 |
timeStamp | number | YES | - | 事件发生时的时间戳 |
# # ScrollToUpperEventDetail Values
name | type | optinal | default | description |
---|---|---|---|---|
direction | string | YES | - | 滚动方向 top 或 left |
# # ScrollToUpperEvent Methods
name | type | required | default | description |
---|---|---|---|---|
stopPropagation | () => void | YES | - | 阻止当前事件的进一步传播 |
preventDefault | () => void | YES | - | 阻止当前事件的默认行为 |
# # ScrollToLowerEvent
# # ScrollToLowerEvent Values
name | type | required | default | description |
---|---|---|---|---|
detail | ScrollToLowerEventDetail | YES | - | - |
type | string | YES | - | 事件类型 |
target | Element | YES | - | 触发事件的组件 |
currentTarget | Element | YES | - | 当前组件 |
timeStamp | number | YES | - | 事件发生时的时间戳 |
# # ScrollToLowerEventDetail Values
name | type | optinal | default | description |
---|---|---|---|---|
direction | string | YES | - | 滚动方向 bottom 或 right |
# # ScrollToLowerEvent Methods
name | type | required | default | description |
---|---|---|---|---|
stopPropagation | () => void | YES | - | 阻止当前事件的进一步传播 |
preventDefault | () => void | YES | - | 阻止当前事件的默认行为 |
# # ScrollEvent
# # ScrollEvent Values
name | type | required | default | description |
---|---|---|---|---|
detail | ScrollEventDetail | YES | - | - |
type | string | YES | - | 事件类型 |
target | Element | YES | - | 触发事件的组件 |
currentTarget | Element | YES | - | 当前组件 |
timeStamp | number | YES | - | 事件发生时的时间戳 |
# # ScrollEventDetail Values
name | type | optinal | default | description |
---|---|---|---|---|
scrollTop | number | YES | - | 竖向滚动的距离 |
scrollLeft | number | YES | - | 横向滚动的距离 |
scrollHeight | number | YES | - | 滚动区域的高度 |
scrollWidth | number | YES | - | 滚动区域的宽度 |
deltaY | number | YES | - | 当次滚动事件竖向滚动量 |
deltaX | number | YES | - | 当次滚动事件横向滚动量 |
# # ScrollEvent Methods
name | type | required | default | description |
---|---|---|---|---|
stopPropagation | () => void | YES | - | 阻止当前事件的进一步传播 |
preventDefault | () => void | YES | - | 阻止当前事件的默认行为 |
# # StartNestedScrollEvent
# # StartNestedScrollEvent Values
name | type | required | default | description |
---|---|---|---|---|
node | Element | YES | - | 开始滚动子节点对象 |
type | string | YES | - | 事件类型 |
target | Element | YES | - | 触发事件的组件 |
currentTarget | Element | YES | - | 当前组件 |
timeStamp | number | YES | - | 事件发生时的时间戳 |
# # StartNestedScrollEvent Methods
name | type | required | default | description |
---|---|---|---|---|
stopPropagation | () => void | YES | - | 阻止当前事件的进一步传播 |
preventDefault | () => void | YES | - | 阻止当前事件的默认行为 |
# # NestedPreScrollEvent
# # NestedPreScrollEvent Values
name | type | required | default | description |
---|---|---|---|---|
deltaX | number | YES | - | x轴滚动距离 |
deltaY | number | YES | - | y轴滚动距离 |
type | string | YES | - | 事件类型 |
target | Element | YES | - | 触发事件的组件 |
currentTarget | Element | YES | - | 当前组件 |
timeStamp | number | YES | - | 事件发生时的时间戳 |
# # NestedPreScrollEvent Methods
name | type | required | default | description |
---|---|---|---|---|
consumed | (consumedX: number, consumedY: number) => void | YES | - | 通知到子节点x,y轴滚动距离的消耗 |
stopPropagation | () => void | YES | - | 阻止当前事件的进一步传播 |
preventDefault | () => void | YES | - | 阻止当前事件的默认行为 |
# # Example
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1">
<!-- #endif -->
<page-head title="scroll-view,区域滚动视图"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
<text class="uni-title-text">Vertical Scroll</text>
<text class="uni-subtitle-text">纵向滚动</text>
</view>
<scroll-view :scroll-top="scrollTop" :scroll-y="true" class="scroll-Y" scroll-with-animation="true"
@scrolltoupper="upper" @scrolltolower="lower" @scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red"><text class="text">A</text></view>
<view id="demo2" class="scroll-view-item uni-bg-green"><text class="text">B</text></view>
<view id="demo3" class="scroll-view-item uni-bg-blue"><text class="text">C</text></view>
</scroll-view>
</view>
<view @tap="goTop" class="uni-center uni-common-mt">
<text class="uni-link">点击这里返回顶部</text>
</view>
<view class="uni-title uni-common-mt">
<text class="uni-title-text">Horizontal Scroll</text>
<text class="uni-subtitle-text">横向滚动</text>
</view>
<scroll-view class="scroll-view_H" :scroll-x="true" @scroll="scroll" :scroll-left="120">
<view id="demo1" class="scroll-view-item_H uni-bg-red"><text class="text">A</text></view>
<view id="demo2" class="scroll-view-item_H uni-bg-green"><text class="text">B</text></view>
<view id="demo3" class="scroll-view-item_H uni-bg-blue"><text class="text">C</text></view>
</scroll-view>
</view>
<navigator url="/pages/component/scroll-view/scroll-view-props" hover-class="none">
<button type="primary" class="button default-button">
非下拉刷新的属性示例
</button>
</navigator>
<view class="uni-common-pb"></view>
<navigator url="/pages/component/scroll-view/scroll-view-refresher-props" hover-class="none">
<button type="primary" class="button default-button">
下拉刷新的属性示例
</button>
</navigator>
<view class="uni-common-pb"></view>
<navigator url="/pages/component/scroll-view/scroll-view-refresher" hover-class="none">
<button type="primary" class="button default-button"> 默认下拉刷新示例 </button>
</navigator>
<view class="uni-common-pb"></view>
<navigator url="/pages/component/scroll-view/scroll-view-custom-refresher-props" hover-class="none">
<button type="primary" class="button default-button">
自定义下拉刷新示例
</button>
</navigator>
<view class="uni-common-pb"></view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts">
export default {
data() {
return {
scrollTop: 0,
oldScrollTop: 0,
methods: {
upper: function (e : ScrollToUpperEvent) {
console.log(e)
lower: function (e : ScrollToLowerEvent) {
console.log(e)
scroll: function (e : ScrollEvent) {
this.oldScrollTop = e.detail.scrollTop
goTop: function () {
// 解决view层不同步的问题
this.scrollTop = this.oldScrollTop
this.$nextTick(function () {
this.scrollTop = 0
uni.showToast({
icon: 'none',
title: '纵向滚动 scrollTop 值已被修改为 0',
</script>
<style>
.scroll-Y {
height: 300rpx;
.scroll-view_H {
width: 100%;
flex-direction: row;
.scroll-view-item {
height: 300rpx;
justify-content: center;
align-items: center;
.scroll-view-item_H {
width: 690rpx;
height: 300rpx;
justify-content: center;
align-items: center;
.text {
font-size: 36rpx;
color: #ffffff;
.button {
margin-top: 30rpx;
</style>
# 自定义下拉刷新样式
-
设置
refresher-default-style
属性为 none 不使用默认样式 - 自定义下拉刷新元素必须要声明为 slot="refresher",需要设置刷新元素宽高信息否则可能无法正常显示!
- 通过组件提供的refresherpulling、refresherrefresh、refresherrestore、refresherabort下拉刷新事件调整自定义下拉刷新元素!实现预期效果
注意: 目前自定义下拉刷新元素不支持放在scroll-view的首个子元素位置上。可能无法正常显示
<scroll-view refresher-default-style="none" :refresher-enabled="true" :refresher-triggered="refresherTriggered"
@refresherpulling="onRefresherpulling" @refresherrefresh="onRefresherrefresh"
@refresherrestore="onRefresherrestore" style="flex:1" >
<view v-for="i in 20" class="content-item">
<text class="text">item-{{i}}</text>
</view>
<!-- 自定义下拉刷新元素 -->
<view slot="refresher" class="refresh-box">
<text class="tip-text">{{text[state]}}</text>
</view>
</scroll-view>
具体代码请参考: 自定义下拉刷新样式示例
# nested-scroll嵌套滚动协商
嵌套滚动是原生才有的概念,web没有。
它是指父子2个滚动容器嵌套,在滚动时可以互相协商,控制父容器怎么滚、子容器怎么滚。
-
通过在子滚动容器设置
custom-nested-scroll = true
,开启与父组件实现嵌套滚动协商。仅list-view、scroll-view组件支持与父组件嵌套滚动协商。
下面的示例代码,在一个scroll-view中嵌套了一个list-view。在list-view上设置了custom-nested-scroll="true"。
<scroll-view style="height: 100%;" scroll-y="true" rebound ="false" nested-scroll-child="listview" @startnestedscroll="onStartNestedScroll" @nestedprescroll="onNestedPreScroll"
@stopnestedscroll="onStopNestedScroll">
<view style="height: 100px;">停靠视图</view>
<list-view id="listview" class="child-scroll" scroll-y="true" custom-nested-scroll="true">
</list-view>
</scroll-view>
-
子组件准备滚动时会触发父组件的
startnestedscroll
事件。父组件响应startnestedscroll
事件return ture则表示与子组件建立嵌套滚动协商。
onStartNestedScroll(event: StartNestedScrollEvent): Boolean {
//开启与子组件建立嵌套滚动协商
return true
-
当建立嵌套滚动协商后,子组件滚动时父组件会持续收到
nestedprescroll
事件,这个事件的含义是嵌套滚动即将发生。 事件中会返回NestedPreScrollEvent子组件将要滚动的数据。 -
父组件执行NestedPreScrollEvent.consumed(x,y)函数,告知子组件本次
nestedprescroll
事件deltaX、deltaY各消耗多少,即父组件要消费掉多少滚动距离。 子组件将执行差值后的deltaX、deltaY滚动距离,也就是剩余的滚动余量留给子组件。
onNestedPreScroll(event: NestedPreScrollEvent) {
var deltaY = event.deltaY
var deltaX = event.deltaX
if() {
//告知子组件deltaX、deltaY各消耗多少
event.consumed(x, y)
-
父组件配置
nested-scroll-child
后,父组件惯性滚动时会让nested-scroll-child
配置的子元素进行滚动。从而触发nestedprescroll
协商处理滚动事件 -
滚动行为停止后会触发
stopnestedscroll
事件
注意:
- 仅Android平台支持嵌套滚动协商
- 嵌套滚动协商仅支持竖向滚动,横向滚动不支持
- nested-scroll-child设置的元素必须配置custom-nested-scroll = true,否则配置无效。
具体代码请参考: nested-scroll嵌套滚动示例
# # Compatibility
Android version | Android uni-app | Android uni-app-x | iOS version | iOS uni-app | iOS uni-app-x | |
---|---|---|---|---|---|---|
scroll-view | 5.0 | √ | 3.9+ | 9.0 | √ | - |
scroll-x | 5.0 | √ | 3.9+ | - | - | - |
scroll-y | 5.0 | √ | 3.9+ | - | - | - |
rebound | 5.0 | x | 3.9+ | - | - | - |
upper-threshold | 5.0 | √ | 3.9+ | - | - | - |
lower-threshold | 5.0 | √ | 3.9+ | - | - | - |
scroll-top | 5.0 | √ | 3.9+ | - | - | - |
scroll-left | 5.0 | √ | 3.9+ | - | - | - |
scroll-into-view | 5.0 | √ | 3.9+ | - | - | - |
scroll-with-animation | 5.0 | √ | 3.9+ | - | - | - |
refresher-enabled | 5.0 | √ | 3.9+ | - | - | - |
refresher-threshold | 5.0 | √ | 3.9+ | - | - | - |
refresher-max-drag-distance | 5.0 | x | 3.9+ | - | - | - |
refresher-default-style | 5.0 | √ | 3.9+ | - | - | - |
refresher-background | 5.0 | √ | 3.9+ | - | - | - |
refresher-triggered | 5.0 | √ | 3.9+ | - | - | - |
show-scrollbar | 5.0 | √ | 3.9+ | - | - | - |
custom-nested-scroll | 5.0 | x | 3.9+ | 9.0 | √ | - |
nested-scroll-child | 5.0 | x | 3.97 | 9.0 | x | - |
@refresherpulling | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@refresherrefresh | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@refresherrestore | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@refresherabort | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@scrolltoupper | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@scrolltolower | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@scroll | 5.0 | √ | 3.9+ | 9.0 | √ | - |
@startnestedscroll | 5.0 | x | 3.9+ | 9.0 | x | - |
@nestedprescroll | 5.0 | x | 3.9+ | 9.0 | x | - |
@stopnestedscroll | 5.0 | x | 3.9+ | 9.0 | x | - |
# # See also
# Bug & Tips
- scroll-view组件的overflow属性不支持配置visible