uniapp vue3 waterfall如何实现瀑布流布局

在uniapp的vue3项目中,如何实现类似瀑布流的布局效果?目前官方没有提供现成的waterfall组件,尝试过使用flex和grid布局但无法实现动态高度图片的错落排列效果。请问有没有成熟的解决方案或第三方组件推荐?最好能支持动态加载数据和响应式布局。

2 回复

在uniapp vue3中实现瀑布流布局,可以使用<waterfall>组件(需安装uni-ui插件),或使用flex布局配合column-count属性。推荐使用waterfall组件,简单高效,支持动态加载数据。


在 UniApp + Vue3 中实现瀑布流布局,可以通过以下两种常用方法实现:

方法一:使用 CSS 多列布局

<template>
  <view class="waterfall-container">
    <view 
      v-for="(item, index) in list" 
      :key="index" 
      class="waterfall-item"
    >
      <image :src="item.image" mode="widthFix" />
      <text class="title">{{ item.title }}</text>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue'

const list = ref([
  // 你的数据数组,包含 image 和 title
])
</script>

<style scoped>
.waterfall-container {
  column-count: 2; /* 列数 */
  column-gap: 10px; /* 列间距 */
  padding: 10px;
}

.waterfall-item {
  break-inside: avoid; /* 防止元素被分割 */
  margin-bottom: 10px;
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.waterfall-item image {
  width: 100%;
  display: block;
}

.title {
  display: block;
  padding: 8px;
  font-size: 14px;
  color: #333;
}
</style>

方法二:使用 JavaScript 计算布局(推荐)

<template>
  <view class="waterfall-wrapper">
    <view class="waterfall-column" v-for="(column, colIndex) in columns" :key="colIndex">
      <view 
        class="waterfall-item" 
        v-for="item in column" 
        :key="item.id"
      >
        <image :src="item.image" mode="widthFix" />
        <text class="title">{{ item.title }}</text>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const list = ref([
  // 你的数据
  { id: 1, image: '/static/1.jpg', title: '标题1', height: 200 },
  { id: 2, image: '/static/2.jpg', title: '标题2', height: 150 },
  // ...更多数据
])

const columns = ref([[], []]) // 两列

// 计算瀑布流布局
const calculateWaterfall = () => {
  const tempColumns = [[], []]
  let colHeights = [0, 0] // 记录每列当前高度
  
  list.value.forEach(item => {
    // 找到高度较小的列
    const minHeightIndex = colHeights[0] <= colHeights[1] ? 0 : 1
    
    tempColumns[minHeightIndex].push(item)
    colHeights[minHeightIndex] += item.height || 100 // 使用预设高度或默认值
  })
  
  columns.value = tempColumns
}

onMounted(() => {
  calculateWaterfall()
})
</script>

<style scoped>
.waterfall-wrapper {
  display: flex;
  padding: 10px;
  gap: 10px;
}

.waterfall-column {
  flex: 1;
}

.waterfall-item {
  margin-bottom: 10px;
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.waterfall-item image {
  width: 100%;
  display: block;
}

.title {
  display: block;
  padding: 8px;
  font-size: 14px;
  color: #333;
}
</style>

推荐使用方法二的原因:

  1. 更好的兼容性:CSS多列布局在某些平台上可能支持不完善
  2. 更精确的控制:可以动态计算图片高度,实现真正的瀑布流效果
  3. 性能优化:可以添加懒加载、虚拟滚动等优化

优化建议:

  • 如果图片高度不确定,可以使用 @load 事件获取实际高度
  • 添加下拉刷新和上拉加载更多功能
  • 考虑使用第三方组件如 uv-ui 的瀑布流组件

选择哪种方法取决于你的具体需求和兼容性要求。

回到顶部