Skip to content

Waterflow 瀑布流 1.1.6

手机扫码预览
17:42

组件名:rice-waterflow

瀑布流布局看起来像瀑布一样错落有致,常用于展示图片和商品

平台兼容性

uni-app x

AndroidiOSiOS(Vapor)HarmonyOSHarmonyOS(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交叉轴元素数量Numnber2
mainAxisGap主轴方向间隔 ,即每个item上下的间距Number0
crossAxisGap交叉轴方向间隔,即每列之间的间距Number0
associativeContainer关联的滚动容器 合法值:nested-scroll-viewString-
bounces控制是否回弹效果Booleantrue
upperThreshold距顶部多远时(单位px),触发 scrolltoupper 事件Number50
lowerThreshold距底部(单位px),触发 scrolltolower 事件Number50
scrollTop设置竖向滚动条位置Number0
showScrollbar控制是否出现滚动条Booleantrue
scrollWithAnimation是否在设置滚动条位置时使用滚动动画Booleantrue
refresherEnabled是否开启下拉刷新,Booleanfalse
refresherDefaultStyle设置下拉刷新默认样式,支持设置 black | white | none, none 表示不使用默认样式Stringblack
refresherBackground设置下拉刷新区域背景颜色,默认透明String-
refresherTriggered设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发Booleanfalse
enableBackToTopiOS点击顶部状态栏滚动条返回顶部Booleanfalse
customNestedScroll子元素是否开启嵌套滚动 将滚动事件与父元素协商处理,默认false,仅针对APPBooleanfalse

WaterflowItem Props

参数说明类型默认值
type对应flow-item的类型 waterflow 将对同类型条目进行复用,所以合理的类型拆分,可以很好地提升 waterflow 性能number0

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)