vue实现瀑布流布局
Vue 实现瀑布流布局
使用 CSS 多列布局
CSS 的 column-count 和 column-gap 属性可以快速实现瀑布流效果。适用于内容高度不一致的场景。
<template>
<div class="waterfall-container">
<div v-for="(item, index) in items" :key="index" class="waterfall-item">
<!-- 内容 -->
<img :src="item.image" :alt="item.title">
<h3>{{ item.title }}</h3>
</div>
</div>
</template>
<style>
.waterfall-container {
column-count: 3;
column-gap: 15px;
}
.waterfall-item {
break-inside: avoid;
margin-bottom: 15px;
}
</style>
使用 JavaScript 计算布局
通过 JavaScript 动态计算每个元素的位置,实现更灵活的瀑布流布局。
<template>
<div class="waterfall" ref="waterfall">
<div
v-for="(item, index) in items"
:key="index"
class="item"
:style="{ top: `${item.top}px`, left: `${item.left}px`, width: `${itemWidth}px` }"
>
<!-- 内容 -->
<img :src="item.image" :alt="item.title">
<h3>{{ item.title }}</h3>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [],
itemWidth: 200,
columns: 3,
columnHeights: []
}
},
mounted() {
this.initWaterfall();
window.addEventListener('resize', this.initWaterfall);
},
methods: {
initWaterfall() {
const containerWidth = this.$refs.waterfall.offsetWidth;
this.itemWidth = (containerWidth - 20 * (this.columns - 1)) / this.columns;
this.columnHeights = new Array(this.columns).fill(0);
this.items = this.items.map(item => {
const minHeight = Math.min(...this.columnHeights);
const columnIndex = this.columnHeights.indexOf(minHeight);
item.top = minHeight;
item.left = columnIndex * (this.itemWidth + 20);
this.columnHeights[columnIndex] += item.height + 10;
return item;
});
}
}
}
</script>
<style>
.waterfall {
position: relative;
}
.item {
position: absolute;
transition: all 0.3s;
}
</style>
使用第三方库
现有的 Vue 瀑布流组件可以快速实现功能,如 vue-waterfall 或 vue-masonry。
安装 vue-waterfall:
npm install vue-waterfall --save
使用示例:
<template>
<waterfall :col="3" :data="items">
<template>
<div class="cell-item" v-for="(item, index) in items" :key="index">
<img :src="item.image" :alt="item.title">
<h3>{{ item.title }}</h3>
</div>
</template>
</waterfall>
</template>
<script>
import Waterfall from 'vue-waterfall';
export default {
components: { Waterfall },
data() {
return {
items: [] // 你的数据
}
}
}
</script>
响应式处理
为适应不同屏幕尺寸,可以动态调整列数:
computed: {
columnCount() {
const width = window.innerWidth;
if (width < 600) return 1;
if (width < 900) return 2;
return 3;
}
}
然后在布局方法中使用这个计算属性。
图片懒加载
结合 IntersectionObserver 实现图片懒加载,优化性能:
methods: {
lazyLoadImages() {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
}
}
在模板中使用:
<img :data-src="item.image" alt="...">






