局部滚动容器组件
前言
在 Uniapp 开发中,scroll-view
组件是一种强大的局部滚动容器,能够在限定的区域内实现 横向或纵向滚动,适用于 长列表、轮播图、消息列表、动态内容 等应用场景。它不仅支持基础的滚动功能,还提供了 滚动事件监听、自定义下拉刷新、滚动动画控制 等高级特性。
# 1. scroll-view
组件简介
# 1.1 什么是 scroll-view
组件?
scroll-view
组件是 Uniapp 提供的 局部滚动视图,它允许 用户通过拖动、滑动 在固定范围内滚动内容,而不会影响页面的整体滚动。
相较于 全页面滚动,scroll-view
组件适用于 局部区域滚动,例如:
- 长列表滚动:如聊天记录、商品列表等
- 横向滑动组件:如轮播图、标签页导航等
- 表单区域滚动:适用于表单较长的情况
但需要注意:
- 在
Webview
渲染模式下,scroll-view
的滚动性能可能 不如页面级滚动,对于 长列表数据 建议使用better-scroll
或 虚拟列表 来提升流畅度。
# 1.2 scroll-view
组件的主要功能
✅ 局部滚动:支持 横向滚动 (scroll-x
) 和 纵向滚动 (scroll-y
)。
✅ 滚动事件监听:支持 @scroll
事件,可以获取当前滚动位置。
✅ 触底/触顶监听:支持 @scrolltoupper
和 @scrolltolower
事件,方便实现 懒加载 和 上拉加载更多。
✅ 自定义下拉刷新:支持 refresher-enabled
及相关事件,实现 下拉刷新功能。
✅ 滚动动画:支持 scroll-with-animation
,可以平滑地移动滚动条位置。
✅ 滚动定位:支持 scroll-top
、scroll-left
、scroll-into-view
,可以直接控制滚动条位置。
# 2. scroll-view
组件的核心属性与事件
# 2.1 主要属性解析
scroll-view
提供了多个自定义属性,控制 滚动方向、动画、事件监听 等行为。以下是常用属性解析:
# 📌 滚动控制相关
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
scroll-x | Boolean | false | 是否允许横向滚动 |
scroll-y | Boolean | false | 是否允许纵向滚动 |
scroll-top | Number | 无 | 控制纵向滚动条位置 |
scroll-left | Number | 无 | 控制横向滚动条位置 |
scroll-into-view | String | 无 | 滚动到指定子元素(子元素的 id 值) |
scroll-with-animation | Boolean | false | 是否在滚动时使用动画过渡 |
# 📌 事件监听相关
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
upper-threshold | Number | 50 | 触发 scrolltoupper 事件的距离 |
lower-threshold | Number | 50 | 触发 scrolltolower 事件的距离 |
enable-back-to-top | Boolean | false | iOS 状态栏点击返回顶部(仅支持 scroll-y ) |
# 📌 自定义下拉刷新
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
refresher-enabled | Boolean | false | 是否开启自定义下拉刷新 |
refresher-threshold | Number | 45 | 触发下拉刷新的阈值 |
refresher-background | String | #FFF | 下拉刷新背景颜色 |
refresher-triggered | Boolean | false | 当前下拉刷新状态 |
# 2.2 主要事件监听
在 Uniapp 的 scroll-view
组件中,除了基本的滚动功能,它还提供了多个 事件监听,可以用于:
- 检测滚动位置
- 触发加载更多
- 自定义下拉刷新
- 实现滚动动画和交互
# 📌 常见事件列表
事件名 | 触发时机 | 说明 |
---|---|---|
@scroll | 滚动时触发 | 可获取 scrollLeft 、scrollTop 等滚动信息 |
@scrolltoupper | 滚动到顶部 / 左边触发 | 适用于 懒加载 或触发刷新 |
@scrolltolower | 滚动到底部 / 右边触发 | 适用于 加载更多数据 |
@refresherpulling | 下拉刷新被拉动时触发 | 监听 用户的下拉操作 |
@refresherrefresh | 触发下拉刷新 | 当下拉刷新触发时调用该事件 |
@refresherrestore | 下拉刷新恢复 | 当刷新完成,列表回到初始状态时触发 |
@refresherabort | 下拉刷新被中止 | 当用户取消下拉刷新时触发 |
# 📌 监听 scroll
事件(获取滚动位置)
<scroll-view class="scroll-Y" scroll-y="true" @scroll="handleScroll">
<view v-for="(item, index) in 20" :key="index" class="scroll-item">
Item {{ index + 1 }}
</view>
</scroll-view>
<script setup>
const handleScroll = (e) => {
console.log("滚动位置:", e.detail.scrollTop) // 获取当前滚动条位置
}
</script>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
作用:获取滚动 实时位置,可用于 导航条透明度渐变、滚动回到顶部按钮 等功能。
# 📌 监听 scrolltolower
事件(触底加载更多)
<scroll-view class="scroll-Y" scroll-y="true" @scrolltolower="loadMoreData">
<view v-for="(item, index) in list" :key="index" class="scroll-item">
{{ item }}
</view>
</scroll-view>
<script setup>
import { ref } from 'vue'
const list = ref(Array.from({ length: 10 }, (_, i) => `Item ${i + 1}`))
const loadMoreData = () => {
console.log("触底了,加载更多数据...")
setTimeout(() => {
list.value.push(...Array.from({ length: 5 }, (_, i) => `新数据 ${i + 1}`))
}, 1000)
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
作用:
- 监听滚动到底部
- 动态加载更多数据
- 适用于商品列表、新闻列表等
# 📌 监听 scrolltoupper
事件(滚动到顶部)
<scroll-view class="scroll-Y" scroll-y="true" @scrolltoupper="handleTop">
<view v-for="(item, index) in 20" :key="index" class="scroll-item">
Item {{ index + 1 }}
</view>
</scroll-view>
<script setup>
const handleTop = () => {
console.log("滚动到顶部")
}
</script>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
作用:
- 检测用户是否回到了顶部
- 可以在顶部显示 “返回顶部” 按钮
# 📌 实现自定义下拉刷新
<scroll-view class="scroll-Y" scroll-y="true"
refresher-enabled="true"
@refresherpulling="onPulling"
@refresherrefresh="onRefresh"
@refresherrestore="onRestore"
@refresherabort="onAbort">
<view v-for="(item, index) in list" :key="index" class="scroll-item">
{{ item }}
</view>
</scroll-view>
<script setup>
const isRefreshing = ref(false)
const onPulling = (e) => {
console.log("下拉中...", e)
}
const onRefresh = () => {
console.log("刷新触发,加载数据中...")
isRefreshing.value = true
setTimeout(() => {
isRefreshing.value = false
console.log("刷新完成")
}, 1500)
}
const onRestore = () => {
console.log("下拉刷新恢复")
}
const onAbort = () => {
console.log("下拉刷新被中止")
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
作用:
- 监听下拉动作
- 触发数据刷新
- 处理恢复、终止刷新
# 3. scroll-view
组件使用
# 3.1 纵向滚动案例
🌟 需求:
- 在
scroll-view
组件中实现 纵向滚动 - 监听 滚动事件
- 实现 点击按钮返回顶部
<template>
<view>
<!-- 纵向滚动区域 -->
<scroll-view class="scroll-Y" scroll-y="true" :scroll-top="scrollTop"
@scroll="handleScroll" @scrolltoupper="handleUpper" @scrolltolower="handleLower">
<view v-for="(item, index) in 20" :key="index" class="scroll-item">
Item {{ index + 1 }}
</view>
</scroll-view>
<!-- 返回顶部按钮 -->
<view class="go-top-btn" @click="goTop">返回顶部</view>
</view>
</template>
<script setup>
import { ref, nextTick } from 'vue'
const scrollTop = ref(0)
const handleScroll = (e) => {
console.log("滚动中:", e.detail.scrollTop)
}
const handleUpper = () => {
console.log("滚动到顶部")
}
const handleLower = () => {
console.log("滚动到底部")
}
// 点击返回顶部
const goTop = () => {
scrollTop.value = 0
nextTick(() => {
uni.showToast({ title: '返回顶部', icon: 'none' })
})
}
</script>
<style scoped>
.scroll-Y {
height: 400rpx;
border: 1px solid #ddd;
}
.scroll-item {
height: 100rpx;
line-height: 100rpx;
text-align: center;
background-color: #f3f3f3;
margin-bottom: 10rpx;
}
.go-top-btn {
text-align: center;
background-color: #007aff;
color: white;
padding: 10rpx;
margin-top: 20rpx;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 3.2 横向滚动案例
🌟 需求:
- 横向滑动
- 默认滑动到
scroll-left=120
- 监听滚动事件
<scroll-view class="scroll-X" scroll-x="true" scroll-left="120" @scroll="handleScroll">
<view v-for="(item, index) in 5" :key="index" class="scroll-item-H">
Item {{ index + 1 }}
</view>
</scroll-view>
<style scoped>
.scroll-X {
white-space: nowrap;
width: 100%;
border: 1px solid #ddd;
}
.scroll-item-H {
display: inline-block;
width: 200rpx;
text-align: center;
line-height: 100rpx;
background-color: #cceeff;
margin-right: 10rpx;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
编辑此页 (opens new window)
上次更新: 2025/02/01, 02:18:15