<template>
<div class="water-layout">
<div
class="img-box default-card-animation"
v-for="(item, index) in imgsArr_c"
:key="index"
:style="{ width: imgWidth + 'px', height: item._height + 'px' }"
ref="imgBox"
>
<img :src="item.src" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
imgsArr: [
{
src:"https://img0.baidu.com/it/u=3130638399,1281069824&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800",
},
{
src:"https://www.ssfiction.com/wp-content/uploads/2020/08/20200820_5f3ec7b395648.jpg",
},
{
src:"https://uploadfile.bizhizu.cn/up/63/2a/a6/632aa6024fe8936ec7fe5c2e80abbe06.jpg.source.jpg",
},
{
src:"https://img0.baidu.com/it/u=3130638399,1281069824&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800",
},
], //为图片数组
imgsArr_c:[], //处理之后的数组
loadedCount: 0, // 为已预处理好的图个数
imgWidth:200, // 为图片的宽度
beginIndex:0,
colsHeightArr:[],
imgBoxEls:null, //所有的dom
colWidth:"50%", //列宽
colNum:2,
};
},
created(){
this.preLoad()
},
methods: {
// 预加载 目的==》设置并保存图片宽高
preLoad() {
// forEach 无法通过 item 直接修改数组元素,需用数组下标修改
console.log("preload函数开始执行了哦哦")
this.imgsArr.forEach((item, index) => {
console.log(item,"函数开始执行了了来了 噜啦噜啦嘞绿绿绿绿绿绿绿")
if (index < this.loadedCount) return;
// 无图则把高度设置为0
if (!item.src) {
console.log("现在我到底是有图还是没有图")
// 图片的高度
this.imgsArr[index]._height = "0";
++this.loadedCount;
// 当前图片都与处理完,则加载图片
if (this.imgsArr.length === this.loadedCount) {
this.preloaded();
}
} else {
console.log("有图src请执行我卡卡卡卡卡卡卡卡扩扩扩扩扩扩")
let img = new Image();
img.src = item.src;
console.log(img,"我是img对象香对象对象对象对象对象卡卡卡卡卡卡卡卡扩扩扩")
img.onload = img.onerror = (e) => {
// 若加载失败则设置图片高度与宽度一致,加载成功则动态计算图片高度
console.log(e,"图片onload,事件对象————————————————————————")
this.imgsArr[index]._height =
e.type === "load"
? Math.round(this.imgWidth * (img.height / img.width))
: this.imgWidth;
if (e.type === "error") {
this.imgsArr[index]._error = true;
}
++this.loadedCount;
// 当前图片都与处理完,则加载图片
if (this.imgsArr.length === this.loadedCount) {
this.preloaded();
}
};
}
});
},
//渲染
preloaded() {
// 开始渲染
this.imgsArr_c = [].concat(this.imgsArr);
this.$nextTick(() => {
// 对每个元素进行排列
this.waterfall();
});
},
// waterfall,等到整个视图都渲染完毕再执行 排列布局
waterfall() {
console.log("排列函数执行了了了了 啦啦啦啦啦啦")
// 选择所有图片dom
this.imgBoxEls = this.$refs["imgBox"];
// 若没图片,则返回
if (!this.imgBoxEls) return;
let top, left, height;
// 开始排列的坐标,若为0则重头排列,colsHeightArr 数组保存的是当前每一列的高度
if (this.beginIndex === 0) this.colsHeightArr = [];
for (let i = this.beginIndex; i < this.imgBoxEls.length; ++i) {
console.log("瀑布流量获取到所哟的dom ",this.imgBoxEls[i])
if (!this.imgBoxEls[i]) return;
// 当前图片的高度 获取高度关键点
height = this.imgBoxEls[i].offsetHeight;
// 第一行,则直接按顺序排列
if (i < this.colNum) {
this.colsHeightArr.push(height);
top = 0;
// colWidth 为列宽,等于图片宽度加 div 左右的padding,colWidth = imgWdith + 2 * padding
left = i * this.colWidth;
} else {
// 找到当前最低的高度和其索引
let minHeight = Math.min.apply(null, this.colsHeightArr);
let minIdx = this.colsHeightArr.indexOf(minHeight);
// 当前图片的 top,即当前图片应所在的高度
top = minHeight;
// 当前图片的 left,即当前图片应该排到目前高度最低那一列下面
left = minIdx * this.colWidth;
// 更新第 minIdx 列的高度
this.colsHeightArr[minIdx] += height;
}
// 设置 img-box 位置
this.imgBoxEls[i].style.top = top + "px";
this.imgBoxEls[i].style.left = left + "px";
// 当前图片在窗口内,则加载,这是用于后面的图片懒加载。viewHeight 为窗口高度
// if (top < this.viewHeight) {
// let imgEl = this.imgBoxEls[i].children[0];
// imgEl.src = imgEl.getAttribute("data-src");
// imgEl.style.opacity = 1;
// imgEl.style.transform = "scale(1)";
// }
}
// 排列完之后,之后新增图片从这个索引开始预加载图片和排列,之前排列的图片无需在处理
this.beginIndex = this.imgBoxEls.length;
},
},
};
</script>
<style scoped>
.img-box{
background-color: #e4e265;
border:1px solid black;
}
.img-box img{
height: 100%;
width: 100%;
}
</style>
瀑布流布局待完善
最新推荐文章于 2024-09-29 23:16:17 发布