vue 瀑布流实现
Vue 瀑布流实现方法
使用 CSS Grid 实现
CSS Grid 提供了一种简单的方式来实现瀑布流布局,无需依赖外部库。通过设置 grid-auto-flow: dense 和自定义列数,可以创建自适应布局。
<template>
<div class="waterfall-container">
<div
v-for="(item, index) in items"
:key="index"
class="waterfall-item"
:style="{ gridRowEnd: `span ${item.span}` }"
>
<!-- 内容区域 -->
</div>
</div>
</template>
<style>
.waterfall-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-flow: dense;
gap: 16px;
}
.waterfall-item {
background: #f0f0f0;
border-radius: 8px;
}
</style>
使用 CSS Columns 实现
CSS 多列布局(column-count)是另一种原生方案,适合内容高度不固定的场景。
<template>
<div class="waterfall-columns">
<div
v-for="(item, index) in items"
:key="index"
class="waterfall-item"
>
<!-- 内容区域 -->
</div>
</div>
</template>
<style>
.waterfall-columns {
column-count: 3;
column-gap: 16px;
}
.waterfall-item {
break-inside: avoid;
margin-bottom: 16px;
}
</style>
使用第三方库 VueWaterfall
对于复杂需求,可选用专为 Vue 设计的瀑布流库如 vue-waterfall,提供动态加载和响应式支持。

安装依赖:
npm install vue-waterfall --save
组件示例:

<template>
<vue-waterfall
:list="items"
:gutterWidth="16"
:cols="3"
>
<template #item="{ item }">
<!-- 自定义内容模板 -->
</template>
</vue-waterfall>
</template>
<script>
import VueWaterfall from 'vue-waterfall';
export default {
components: { VueWaterfall },
data() {
return { items: [...] }
}
}
</script>
动态计算高度(JavaScript 方案)
通过监听元素高度动态调整位置,适合需要精确控制的场景。
mounted() {
this.$nextTick(() => {
const container = this.$el;
const items = container.querySelectorAll('.waterfall-item');
const columnHeights = new Array(3).fill(0);
items.forEach(item => {
const minHeight = Math.min(...columnHeights);
const columnIndex = columnHeights.indexOf(minHeight);
item.style.transform = `translateY(${minHeight}px)`;
columnHeights[columnIndex] += item.clientHeight + 16;
});
container.style.height = `${Math.max(...columnHeights)}px`;
});
}
响应式列数调整
结合 resizeObserver 实现窗口变化时的列数自适应。
data() {
return { columnCount: 3 }
},
mounted() {
const observer = new ResizeObserver(entries => {
const width = entries[0].contentRect.width;
this.columnCount = width < 600 ? 1 : width < 900 ? 2 : 3;
});
observer.observe(this.$el);
},
beforeDestroy() {
observer.disconnect();
}
注意事项
- 图片加载可能导致布局错位,建议使用
loading="lazy"或监听onload事件 - 移动端需考虑触屏滚动性能,避免频繁重排
- 服务端渲染(SSR)场景需兼容客户端动态计算逻辑






