Skip to content

Waterfall 瀑布流

瀑布流布局组件,适用于图片展示、商品列表等场景。组件会自动根据内容高度将数据分配到不同列中,实现瀑布流效果。

基础用法

不使用插槽时,组件会根据 imageField 属性自动渲染图片。

vue
<template>
  <up-waterfall
    :list="waterfallList"
    :column="2"
    @item-click="handleItemClick"
    @load-complete="handleLoadComplete"
  />
</template>

<script setup>
import { ref } from 'vue'
const waterfallList = ref([
  {
    id: 1,
    imgUrl: 'https://picsum.photos/300/400?random=1',
    title: '瀑布流项目 1'
  },
  {
    id: 2,
    imgUrl: 'https://picsum.photos/300/600?random=2',
    title: '瀑布流项目 2'
  }
])

function handleItemClick(item, index) {
  console.log('点击了项目:', item, index)
}

function handleLoadComplete() {
  console.log('瀑布流加载完成')
}
</script>

自定义列数

vue
<template>
  <up-waterfall
    :list="waterfallList"
    :column="3"
    :column-space="1"
    :sort-by-img-info="false"
  />
</template>

自定义渲染

完全自定义每个项目的渲染内容,包括图片和内容。

vue
<template>
  <up-waterfall
    :list="customImageList"
    :column="2"
  >
    <template #default="{ item, onLoad, onError }">
      <image 
        :src="item.imgUrl" 
        mode="aspectFill" 
        class="custom-image" 
        @load="onLoad" 
        @error="onError" 
      />
      <view class="item-content">
        <text class="item-title">{{ item.title }}</text>
        <text class="item-price">¥{{ item.price }}</text>
      </view>
    </template>
  </up-waterfall>
</template>

<style>
.custom-image {
  width: 100%;
  height: 200rpx;
}
</style>

自定义图片源获取方法

通过 getImageSrc 属性可以自定义获取图片源的方法,这在需要对图片 URL 进行特殊处理时很有用。

vue
<template>
  <up-waterfall
    :list="waterfallList"
    :column="2"
    :get-image-src="getCustomImageSrc"
  >
  </up-waterfall>
</template>

<script setup>
const waterfallList = ref([
  {
    id: 1,
    imgUrl: 'https://picsum.photos/300/400?random=1',
    title: '瀑布流项目 1'
  },
  {
    id: 2,
    imgUrl: 'https://picsum.photos/300/600?random=2',
    title: '瀑布流项目 2'
  }
])

// 自定义图片源获取方法 - 简单示例
const getCustomImageSrc = (data) => {
  return data.imgUrl || ''
}

// 自定义图片源获取方法 - 复杂示例
const getCustomImageSrc = (item) => {
  // 可以根据不同的字段获取图片
  if (item.images && item.images.length > 0) {
    return `https://cdn.example.com/${item.images[0]}`
  }
  if (item.thumbnail) {
    return `https://cdn.example.com/${item.thumbnail}`
  }
  if (item.cover) {
    return item.cover
  }
  // 添加默认图片或返回空字符串
  return item.imgUrl || 'https://via.placeholder.com/300x400'
}
</script>

使用场景

  1. 统一图片域名:为所有图片添加 CDN 前缀
  2. 多字段支持:根据不同的数据结构获取图片
  3. 默认图片:当没有图片时显示占位图
  4. 图片处理:添加图片尺寸、质量等参数

注意事项

  • 当传入 getImageSrc 方法时,会优先使用该方法获取图片源,忽略 imageField 属性
  • 开启 sortByImgInfo 后会根据图片高度逐一加载项目,适用于图片高度差异较大的场景
  • 不使用插槽时,组件只会渲染图片,如需显示其他内容请使用默认插槽

是否开启sortByImgInfo

开启 sortByImgInfo 后会根据图片的高度和宽度信息对列表进行排序,确保瀑布流布局的美观,与此同时页面也会产生逐条加载的效果。

vue
<template>
  <up-waterfall
    :list="waterfallList"
    :column="2"
    :sort-by-img-info="true"
  >
  </up-waterfall>
</template>

Props

参数说明类型默认值
list瀑布流数据列表WaterfallItem[][]
column列数number2
columnSpace列间距(百分比)number2
imageField图片字段名string'imgUrl'
getImageSrc获取图片源的方法(item: WaterfallItem) => stringundefined
sortByImgInfo是否根据图片信息排序booleanfalse

Events

事件名说明回调参数
load-complete加载完成时触发-
item-click点击项目时触发(item: WaterfallItem, index: number)
image-load图片加载成功时触发(item: WaterfallItem)
image-error图片加载失败时触发(item: WaterfallItem)

Slots

插槽名说明参数
default自定义项目渲染{ item, index, onLoad, onError }

类型定义

typescript
interface WaterfallItem {
  [key: string]: any
  index?: number
  id?: string | number
}

方法

通过 ref 可以访问到组件实例并调用实例方法。

方法名说明参数
resetWaterfall重置瀑布流(list: WaterfallItem[])
appendNewData追加新数据(newItems: WaterfallItem[])

源代码

文档
组件

Released under the MIT License.

Released under the MIT License.