<template>
<div class="v-waterfall-content" ref="v-waterfall" id="v-waterfall">
<div
v-for="(img, i) in waterfallList"
:key="i"
class="v-waterfall-item"
:style="{
top: img.top + 'px',
left: img.left + 'px',
width: waterfallImgWidth + 'px',
height: img.height,
}"
@click="handleClick(img)"
>
<img :src="img.src" alt="" />
<div class="label">{{ img.label }}</div>
</div>
</div>
</template>
<script>
export default {
name: "v-waterfall",
props: {
imgList: {
type: Array,
default: () => {
return [
{ src: require("@/assets/image/4.jpg"), id: 4, label: "游戏1" },
{ src: require("@/assets/image/5.jpg"), id: 5, label: "游戏1" },
{ src: require("@/assets/image/1.jpg"), id: 1, label: "游戏1" },
{ src: require("@/assets/image/3.jpg"), id: 3, label: "游戏1" },
{ src: require("@/assets/image/2.jpg"), id: 2, label: "游戏1" },
],;
},
required: true,
},
},
data() {
return {
waterfallList: [],
// waterfallImgWidth: 100,
waterfallImgCol: 2,
waterfallImgRight: 10,
waterfallImgBottom: 10,
waterfallDeviationHeight: [],
};
},
computed: {
waterfallImgWidth() {
return (
(this.$el.clientWidth -
(this.waterfallImgCol + 1) * this.waterfallImgRight) /
this.waterfallImgCol
);
},
},
mounted() {
this.calculationWidth();
},
methods: {
handleClick(item) {
console.log(item);
},
//计算每个图片的宽度或者是列数
calculationWidth() {
let domWidth = this.$refs["v-waterfall"].offsetWidth;
if (!this.waterfallImgWidth && this.waterfallImgCol) {
this.waterfallImgWidth =
(domWidth - this.waterfallImgRight * this.waterfallImgCol) /
this.waterfallImgCol;
} else if (this.waterfallImgWidth && !this.waterfallImgCol) {
this.waterfallImgCol = Math.floor(
domWidth / (this.waterfallImgWidth + this.waterfallImgRight)
);
}
//初始化偏移高度数组
this.waterfallDeviationHeight = new Array(this.waterfallImgCol);
for (let i = 0; i < this.waterfallDeviationHeight.length; i++) {
this.waterfallDeviationHeight[i] = 0;
}
this.imgPreloading();
},
//图片预加载
imgPreloading() {
for (let i = 0; i < this.imgList.length; i++) {
let aImg = new Image();
aImg.src = this.imgList[i].src;
aImg.onload = aImg.onerror = () => {
let imgData = {};
imgData.height = (this.waterfallImgWidth / aImg.width) * aImg.height;
let keys = Object.keys(this.imgList[i]);
for (let j = 0; j < keys.length; j++) {
const element = keys[j];
imgData[element] = this.imgList[i][element];
}
this.waterfallList.push(imgData);
this.rankImg(imgData);
};
}
},
//瀑布流布局
rankImg(imgData) {
let {
waterfallImgWidth,
waterfallImgRight,
waterfallImgBottom,
waterfallDeviationHeight,
// waterfallImgCol,
} = this;
//for (let i = 0;i < this.waterfallList.length;i++){
let minIndex = this.filterMin();
imgData.top = waterfallDeviationHeight[minIndex];
imgData.left =
minIndex * (waterfallImgRight + waterfallImgWidth) + waterfallImgRight;
waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;
},
/**
* 找到最短的列并返回下标
* @returns {number} 下标
*/
filterMin() {
const min = Math.min.apply(null, this.waterfallDeviationHeight);
return this.waterfallDeviationHeight.indexOf(min);
},
},
};
</script>
<style lang="scss" scoped>
.v-waterfall-content {
width: 100%;
height: 100%;
position: relative;
}
.v-waterfall-item {
float: left;
position: absolute;
.label {
position: absolute;
bottom: 4px;
left: 0;
width: 100%;
// height: 24px;
background-color: rgba($color: #000, $alpha: 0.5);
color: #fff;
line-height: 24px;
}
}
.v-waterfall-item img {
width: 100%;
height: auto;
}
</style>
07-31
156
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)