vue中实现瀑布流
使用CSS实现瀑布流布局
CSS的column-count和column-gap属性可以快速实现瀑布流效果。这种方法简单但无法实现动态加载。
<template>
<div class="waterfall-container">
<div v-for="(item, index) in items" :key="index" class="waterfall-item">
<!-- 内容 -->
</div>
</div>
</template>
<style>
.waterfall-container {
column-count: 4;
column-gap: 15px;
}
.waterfall-item {
break-inside: avoid;
margin-bottom: 15px;
}
</style>
使用Flexbox实现瀑布流
Flexbox布局结合flex-direction: column和flex-wrap: wrap可以实现更灵活的瀑布流。
<template>
<div class="flex-waterfall">
<div v-for="(item, index) in items" :key="index" class="flex-item">
<!-- 内容 -->
</div>
</div>
</template>
<style>
.flex-waterfall {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 1000px; /* 需要固定高度 */
}
.flex-item {
width: 25%;
padding: 10px;
}
</style>
使用JavaScript计算布局
通过监听元素高度动态计算位置,可以实现更精确的瀑布流效果。
methods: {
calculateWaterfall() {
const container = this.$refs.container;
const items = this.$refs.items;
const columnCount = 4;
const columnHeights = Array(columnCount).fill(0);
items.forEach(item => {
const minHeight = Math.min(...columnHeights);
const columnIndex = columnHeights.indexOf(minHeight);
item.style.position = 'absolute';
item.style.left = `${columnIndex * (100 / columnCount)}%`;
item.style.top = `${minHeight}px`;
columnHeights[columnIndex] += item.offsetHeight;
});
container.style.height = `${Math.max(...columnHeights)}px`;
}
}
使用第三方库
Masonry和vue-waterfall是常用的瀑布流解决方案。
安装vue-waterfall:
npm install vue-waterfall --save
使用示例:
import VueWaterfall from 'vue-waterfall'
export default {
components: {
VueWaterfall
},
data() {
return {
list: [...] // 数据源
}
}
}
<vue-waterfall
:list="list"
:gutter="20"
:width="240"
:breakpoints="{
1200: { rowPerView: 4 },
800: { rowPerView: 3 },
500: { rowPerView: 2 }
}">
<template #item="{item}">
<!-- 自定义内容 -->
</template>
</vue-waterfall>
响应式处理
为适应不同屏幕尺寸,需要添加响应式逻辑。
computed: {
columnCount() {
if (window.innerWidth < 768) return 2;
if (window.innerWidth < 1024) return 3;
return 4;
}
},
mounted() {
window.addEventListener('resize', this.calculateWaterfall);
},
beforeDestroy() {
window.removeEventListener('resize', this.calculateWaterfall);
}
图片懒加载优化
结合IntersectionObserver实现图片懒加载,提升性能。
methods: {
initLazyLoad() {
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('.lazy-img').forEach(img => {
observer.observe(img);
});
}
}






