暗黑模式
Waterflow 瀑布流 1.1.6
手机扫码预览
17:42
组件名:rice-waterflow
瀑布流布局看起来像瀑布一样错落有致,常用于展示图片和商品
平台兼容性
uni-app x
| Android | iOS | iOS(Vapor) | HarmonyOS | HarmonyOS(Vapor) | 微信小程序 | h5 |
|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ |
注意
目前APP蒸汽模式下推荐直接使用官方的waterflow,该组件的属性和方法和rice-waterfolw一致,虽然蒸汽模式下rice-waterfolw 也能使用;
如果布局中有图片等高度不确定的元素,需要在图片加载完成和失败后加载插槽内传递 remeasure 的方法或者调用waterfolw导出的relayout/waterfolw-item 导出的remeasure 方法
上下刷新下拉加载等更多使用示例请参考demo
基本使用
html
<rice-waterflow :main-axis-gap="8" :cross-axis-gap="8" refresher-enabled :refresher-triggered="refresherTriggered"
:bounces="false" refresher-default-style="none" :refresher-threshold="refresherThreshold" :show-scrollbar="false"
:lower-threshold="60" class="waterflow" scroll-with-animation @refresherpulling="onRefresherpulling"
:scroll-top="scrollTop2" @refresherrefresh="onRefresherrefresh" @refresherrestore="onRefresherrestore"
@scrolltolower="onScrolltolower" @scroll="onScroll">
<rice-waterflow-item v-for="(item,index) in list" :key="index" class="waterflow-item">
<template #default="{remeasure}">
<rice-image :src="item.img" class="img" mode="widthFix" :preview-src-list="[item.img]" radius="4px"
@load="remeasure" @error="remeasure" />
<text class="text">{{item.name}}</text>
</template>
</rice-waterflow-item>
<!-- 上拉刷新 -->
<template #refresher>
<view class="custom-refresher">
<rice-loading :text="refresherText[refresherStatus]"></rice-loading>
</view>
</template>
<!-- 加载更多 -->
<template #load>
<view class="custom-load">
<rice-divider v-if="isLoading" text-position="center" :style="{'width':'100px'}">
<rice-loading size="16" />
</rice-divider>
<rice-divider v-if="isFinised" text="到底了" text-position="center" :style="{'width':'100px'}" />
</view>
</template>
</rice-waterflow>js
import { WaterflowList, renderWaterList, getRandomImg } from "@/utils/waterflow"
import { getRandomNum } from "@/utils/tools.uts"
type Props = {
currentIndex : number, //当前激活的index
tabIndex : number,//当前组件位于第几个
}
const props = withDefaults(defineProps<Props>(), {
currentIndex: 0,
tabIndex: 0
})
const firstLoaded = ref(false)
const isLoading = ref(false)
let networkTimer : number | null = null
const refresherTriggered = ref(false)
const refresherText = ref(['继续下拉刷新', '释放立即刷新', '刷新中', ""])
const refresherStatus = ref(0)
/**
* 模拟网络请求
*/
const currentPage = ref(1)
const sleep = () => {
return new Promise((resolve) => {
if (networkTimer != null) clearTimeout(networkTimer!)
const max = currentPage.value == 1 ? 800 : 1500
networkTimer = setTimeout(() => {
resolve(true)
}, getRandomNum(max, 500))
})
}
/**
* 获取数据
*/
const list = ref<WaterflowList[]>([])
const getList = async () => {
if (list.value.length == 0) {
uni.showLoading({
title: '加载中…',
mask: true
})
}
await sleep()
if (list.value.length == 0) {
uni.hideLoading()
}
const result = renderWaterList(list.value.length, 10)
if (currentPage.value == 1) {
list.value = result
} else {
list.value.push(...result)
}
firstLoaded.value = true
isLoading.value = false
await nextTick()
refresherTriggered.value = false
}
/**
* 下拉刷新控件被下拉
*/
const refresherThreshold = ref(60)
const onRefresherpulling = (e : UniRefresherEvent) => {
if (e.detail.dy > refresherThreshold.value) {
refresherStatus.value = 1
} else {
refresherStatus.value = 0
}
}
/**
* 下拉刷新被触发
*/
const onRefresherrefresh = () => {
refresherStatus.value = 2
refresherTriggered.value = true
currentPage.value = 1
getList()
}
/**
* 下拉刷新被复位
*/
const onRefresherrestore = () => {
refresherStatus.value = 3
}
/**
* 加载更多
*/
const isFinised = ref(false)
const onScrolltolower = () => {
console.log('加载更多')
if (isLoading.value) return
//模拟加载完成
if (currentPage.value >= 3 && props.tabIndex == 0) {
isFinised.value = true
uni.showToast({
title: '没有更多了',
icon: 'none'
})
return
}
isLoading.value = true
currentPage.value++
getList()
}
/**
* 容器滚动
*/
const scrollTop = ref(0)
const scrollTop2 = ref(0)
const onScroll = (e : UniScrollEvent) => {
scrollTop.value = e.detail.scrollTop
}
const toTop = () => {
scrollTop2.value = scrollTop.value
nextTick(() => {
scrollTop2.value = 0
scrollTop.value = 0
})
}
watch(() : number => props.currentIndex, async (newVal : number) => {
if (newVal == props.tabIndex) {
//只有第一次滑动才加载数据
if (!firstLoaded.value) {
await nextTick()
//获取数据
getList()
}
}
}, {
immediate: true
})
onUnmounted(() => {
if (networkTimer != null) clearTimeout(networkTimer!)
})API
Waterflow Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| crossAxisCount | 交叉轴元素数量 | Numnber | 2 |
| mainAxisGap | 主轴方向间隔 ,即每个item上下的间距 | Number | 0 |
| crossAxisGap | 交叉轴方向间隔,即每列之间的间距 | Number | 0 |
| associativeContainer | 关联的滚动容器 合法值:nested-scroll-view | String | - |
| bounces | 控制是否回弹效果 | Boolean | true |
| upperThreshold | 距顶部多远时(单位px),触发 scrolltoupper 事件 | Number | 50 |
| lowerThreshold | 距底部(单位px),触发 scrolltolower 事件 | Number | 50 |
| scrollTop | 设置竖向滚动条位置 | Number | 0 |
| showScrollbar | 控制是否出现滚动条 | Boolean | true |
| scrollWithAnimation | 是否在设置滚动条位置时使用滚动动画 | Boolean | true |
| refresherEnabled | 是否开启下拉刷新, | Boolean | false |
| refresherDefaultStyle | 设置下拉刷新默认样式,支持设置 black | white | none, none 表示不使用默认样式 | String | black |
| refresherBackground | 设置下拉刷新区域背景颜色,默认透明 | String | - |
| refresherTriggered | 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发 | Boolean | false |
| enableBackToTop | iOS点击顶部状态栏滚动条返回顶部 | Boolean | false |
| customNestedScroll | 子元素是否开启嵌套滚动 将滚动事件与父元素协商处理,默认false,仅针对APP | Boolean | false |
WaterflowItem Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | 对应flow-item的类型 waterflow 将对同类型条目进行复用,所以合理的类型拆分,可以很好地提升 waterflow 性能 | number | 0 |
WaterflowItem Props
Slots
| 名称 | 说明 | 参数 |
|---|---|---|
| default | 默认插槽,如果有图片,需要在图片的load和error事件中传递remeasure方法 | remeasure 方法 |
该方法在APP端的非蒸汽模式中无实际作用
vue
<template #default="{remeasure}">
<image @load="remeasure" @error="remeasure" />
</template>以下方法在APP端的非蒸汽模式中无实际作用
Waterflow 方法
| 事件名 | 说明 | 参数 |
|---|---|---|
| relayout | 重新排版全部内容,适合一次性对所有的Item进行重新排版 | - |
ts
const waterflowRef = ref<RiceWaterflowComponentPublicInstance | null>(null)
waterflowRef!.relayout()WaterflowItem 方法
| 事件名 | 说明 | 参数 |
|---|---|---|
| remeasure | 重新排版该Item的内容,适合某个Item内容发生改变时调用 | - |
ts
const waterflowItemRef = ref<RiceWaterflowItemComponentPublicInstance | null>(null)
waterflowItemRef?.remeasure()类型定义
组件导出如下类型
ts
import { CheckboxDirection, CheckboxShape, CheckboxIconPosition, CheckboxValueType } from '@/uni_modules/rice-ui'
// 组件类型
const waterflowRef = ref<RiceWaterflowComponentPublicInstance | null>(null)
const waterflowItemRef = ref<RiceWaterflowItemComponentPublicInstance | null>(null)