Vue3 瀑布流 组件(vue2修改部分代码及可适用)
暂未做图片瀑布流的适配。 后续可能会增加。
不多说直接上代码!!!
<template>
<div class="waterfall-row" ref="waterfallRow">
<template v-for="(item, index) of list" :key="item">
<div class="waterfall-col">
<div class="waterfall-card">
<slot :item="item" :index="index"></slot>
</div>
</div>
</template>
</div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref } from "vue";
interface waterfallFlow {
waterfallFlowHeight: Array<number>;
left: number;
rowHeight: number;
}
const props = defineProps({
list: {
type: Object,
default: () => ({}),
},
columns: { // 一共几列,默认为2
type: Number,
default: 2,
},
columnGap: { // 列与列之间的间距,最好设置为双数
type: Number,
default: 10,
},
rowGap: { // 行与行之间的间距,最好设置为双数
type: Number,
default: 10,
},
});
const state: waterfallFlow = reactive({
waterfallFlowHeight: new Array(props.columns).fill(0),
left: Math.floor(100 / props.columns),
rowHeight: 0,
});
const waterfallRow = ref();
const waterfallFlowFun = () => {
const dom = waterfallRow.value.querySelectorAll(".waterfall-col");
dom.forEach((item: any) => {
item.style.position = "absolute";
const minIndex = filterMin();
item.style.left = `calc(${minIndex * state.left}% + ${(props.columnGap / 2) * minIndex}px)`;
const itemColumnGap = props.columnGap * (state.waterfallFlowHeight[minIndex] == 0 ? 0 : 1);
item.style.top = state.waterfallFlowHeight[minIndex] + itemColumnGap + "px";
state.waterfallFlowHeight[minIndex] += item.querySelector(".waterfall-card").offsetHeight + itemColumnGap;
});
state.rowHeight = getrowHeight();
};
const getrowHeight = () => Math.max.apply(null, state.waterfallFlowHeight);
const filterMin = () => {
const min = Math.min.apply(null, state.waterfallFlowHeight);
return state.waterfallFlowHeight.indexOf(min);
};
onMounted(() => {
nextTick(() => {
waterfallFlowFun();
});
});
</script>
<style lang="scss" scoped>
$columnGap: v-bind("props.columnGap");
$columnWidth: v-bind("state.left");
$rowHeight: v-bind("state.rowHeight");
.waterfall-row {
position: relative;
min-height: calc($rowHeight * 1px);
display: flex;
flex-wrap: wrap;
.waterfall-col {
width: calc($columnWidth * 1% - $columnGap * 1px / 2);
.waterfall-card {
padding-left: 0 !important;
padding-right: 0 !important;
margin-top: 0 !important;
}
}
}
</style>
1、创建 组件 直接复制代码写入即可
2、直接引入 vue 组件直接使用即可
<water-fall :list="otherContacts">
<template v-slot="slotProps">
你要写入的内容! slotProps = {item:{},index}
</template>
</water-fall>