一个简单的瀑布流布局实现方法,使用Vue3和Vite技术
背景
在工作中,我们常常需要实现瀑布流布局。今天,我将分享一个简单的实现方法,供大家参考。
技术
- Vue 3
- Vite
HTML
<template>
<div>
<button @click="addCard">增加</button>
<div class="card">
<div class="card-list"
v-waterfall
v-for="(item,index) in list"
:key="index"
:style="{backgroundColor:item.color,height:item.height}">
<p class="text"> {{ index }} </p>
</div>
</div>
</div>
</template>
CSS
注意:由于在JS中使用了transform,所以需要设置定位。
.card {
position: relative;
display: flex;
flex-wrap: wrap;
width: 700px;
}
.card-list {
position: absolute;
width: 200px;
}
JS
实现逻辑
- 声明一个高度数组,保存每列的高度。
- 获取最小高度的位置,方便定位。
- 自定义指令:
v-waterfall
,在mounted
中获取DOM元素。
import { onMounted, ref, nextTick } from "vue";
const list = ref([
{color:'#76da6e', height:'100px'},
{color:'#40a988', height:'70px'},
{color:'#2384c4', height:'120px'},
{color:'#106ba3', height:'80px'},
{color:'#0a589e', height:'110px'},
{color:'#0a4e98', height:'90px'},
{color:'#09408c', height:'100px'},
{color:'#083680', height:'130px'},
]);
const tabulationHeights = ref([0, 0, 0, 0]);
const updateLayout = (el) => {
const columns = getMinTabulationHeight(tabulationHeights.value);
const top = tabulationHeights.value[columns];
const left = columns * el.clientWidth;
el.style.transform = `translate(${left}px,${top}px)`;
tabulationHeights.value[columns] += el.offsetHeight;
}
const getMinTabulationHeight = (arr) => {
let min = Math.min(...arr);
return arr.indexOf(min) !== -1 ? arr.indexOf(min) : 0;
}
const vWaterfall = {
mounted: (el) => {
updateLayout(el);
},
updated: (el) => {
// updateLayout(el);
}
}
// 增加卡片
const addCard = () => {
const height = Math.floor(Math.random() * 50 + 100);
const color = '#' + Math.floor(Math.random() * 16777215).toString(16);
list.value.push({color, height: height + 'px'});
}
问题与处理
有朋友可能会问:列表之间肯定不会没有间隔吧?这很简单。如果要封装一个组件,只需传递一个GAP值,参与计算即可:
const updateLayout = (el) => {
const columns = getMinTabulationHeight(tabulationHeights.value);
const top = tabulationHeights.value[columns] + 20; // 加上间隔
const left = (columns * el.clientWidth) + (columns * 20); // 加上间隔
el.style.transform = `translate(${left}px,${top}px)`;
tabulationHeights.value[columns] += el.offsetHeight + 20; // 更新高度
}
总结
以上只是一个简单的模板,大家可以在此基础上进行优化,以满足自己的需求。今天的分享就到这里,如果觉得不错,请收藏这个源码库,后续会更新插件库!