瀑布流组件
# 瀑布流组件
waterfall
组件是 App
端 nvue
页面中用于实现瀑布流布局的核心组件。瀑布流布局是一种流行的多栏不规则布局,随着页面滚动,还可以不断加载数据并附加到页面的末尾。相比普通的 view
实现,waterfall
组件通过 cell
元素进行优化,能够自动回收渲染资源并提升性能。
# 1. 什么是 waterfall
组件?
waterfall
组件专门用于实现瀑布流式布局,通过将 cell
定义为子组件,waterfall
可以动态地优化渲染性能,特别适合用于长列表、多列布局的场景。它支持列数、列宽、间隙等属性的定制,并能与下拉刷新、上拉加载更多等功能配合使用。
使用场景
- 商品展示页面:用于展示各种商品,布局规则但排列灵活。
- 图片墙:适合用于展示不规则高度的图片。
- 社交内容流:通过
cell
回收机制,高效展示用户生成内容。
# 2. waterfall
组件的常用属性
waterfall
组件提供了丰富的属性用于定制列数、列宽、列间距等布局特性,以下是常用属性的详细说明及使用示例:
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
show-scrollbar | Boolean | true | 控制是否出现滚动条 |
column-count | String | "auto" | 设置瀑布流的列数,可设置具体数值或者 auto 由列宽决定 |
column-width | String | "auto" | 设置瀑布流每列的宽度,auto 表示由列数决定 |
column-gap | String | "normal" | 列与列之间的间隙,normal 表示默认值 32px |
left-gap | String | "0" | 设置左边列与容器的间隙 |
right-gap | String | "0" | 设置右边列与容器的间隙 |
always-scrollable-vertical | Boolean | false | 是否强制内容少时也可以垂直滚动,适用于 iOS 平台 |
# 2.1 设置列数与列宽
- 说明:通过
column-count
和column-width
属性来控制列数与列宽,开发者可以根据布局需求灵活调整。 - 类型:
String
- 默认值:
auto
<template>
<waterfall column-count="2" column-width="auto">
<cell v-for="(item, index) in lists" :key="index">
<text>{{ item }}</text>
</cell>
</waterfall>
</template>
<script setup>
import { ref } from 'vue'
// 定义数据列表
const lists = ref(['A', 'B', 'C', 'D', 'E'])
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2.2 设置列间距与左右间距
- 说明:通过
column-gap
、left-gap
和right-gap
属性控制瀑布流每列之间及左右的间隙。 - 类型:
String
- 默认值:
normal
(对应32px
)
<template>
<waterfall
column-count="3"
column-width="auto"
column-gap="20px"
left-gap="10px"
right-gap="10px"
>
<cell v-for="(item, index) in lists" :key="index">
<text>{{ item }}</text>
</cell>
</waterfall>
</template>
<script setup>
import { ref } from 'vue'
// 定义数据列表
const lists = ref(['A', 'B', 'C', 'D', 'E', 'F', 'G'])
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.3 支持下拉刷新与上拉加载
- 说明:通过
refresh
和loading
组件分别实现下拉刷新与上拉加载更多的功能,结合waterfall
实现流式加载效果。 - 类型:无
<template>
<waterfall column-count="2" column-width="auto" @loadmore="loadMore">
<refresh @refresh="onRefresh">下拉刷新中...</refresh>
<cell v-for="(item, index) in lists" :key="index">
<text>{{ item }}</text>
</cell>
<loading>加载更多...</loading>
</waterfall>
</template>
<script setup>
import { ref } from 'vue'
const lists = ref(['A', 'B', 'C', 'D', 'E'])
// 模拟下拉刷新操作
const onRefresh = () => {
setTimeout(() => {
lists.value = ['F', 'G', 'H', 'I', 'J']
}, 1000)
}
// 模拟上拉加载更多操作
const loadMore = () => {
setTimeout(() => {
lists.value.push(...['K', 'L', 'M'])
}, 1000)
}
</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
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
# 3. 子组件
waterfall
组件的子组件包括以下几种类型,用于支持各种布局和功能:
cell
:用于定义瀑布流中的子列表项,cell
组件会进行内存优化,回收不可见部分的渲染资源。header
:用于定义固定在页面顶部的区域,当内容滚动时,header
会保持在顶部不动。refresh
:用于实现下拉刷新功能。loading
:用于实现上拉加载更多的功能。
# 4. 瀑布流商品列表
以下案例展示了如何使用 waterfall
组件实现商品列表的瀑布流展示,并结合 cell
、refresh
、loading
实现流式加载效果。
<template>
<waterfall
column-count="2"
column-width="auto"
column-gap="20px"
left-gap="10px"
right-gap="10px"
@loadmore="loadMore"
>
<refresh @refresh="onRefresh">下拉刷新中...</refresh>
<!-- 商品列表项 -->
<cell v-for="(item, index) in lists" :key="index">
<view class="item">
<image :src="item.imgUrl" class="product-img" />
<text class="product-name">{{ item.name }}</text>
</view>
</cell>
<loading>加载更多...</loading>
</waterfall>
</template>
<script setup>
import { ref } from 'vue'
// 模拟商品列表数据
const lists = ref([
{ name: '商品 A', imgUrl: '/static/a.jpg' },
{ name: '商品 B', imgUrl: '/static/b.jpg' },
{ name: '商品 C', imgUrl: '/static/c.jpg' },
{ name: '商品 D', imgUrl: '/static/d.jpg' }
])
// 下拉刷新
const onRefresh = () => {
setTimeout(() => {
lists.value = [
{ name: '商品 E', imgUrl: '/static/e.jpg' },
{ name: '商品 F', imgUrl: '/static/f.jpg' }
]
}, 1000)
}
// 上拉加载更多
const loadMore = () => {
setTimeout(() => {
lists.value.push(
{ name: '商品 G', imgUrl: '/static/g.jpg' },
{ name: '商品 H', imgUrl: '/static/h.jpg' }
)
}, 1000)
}
</script>
<style scoped>
.item {
margin-bottom: 20px;
}
.product-img {
width: 100%;
height: 150px;
}
.product-name {
font-size: 16px;
text-align: center;
margin-top: 10px;
}
</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
64
65
66
67
68
69
70
71
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
64
65
66
67
68
69
70
71
编辑此页 (opens new window)
上次更新: 2025/02/01, 02:18:15