vue 基于原生JS实现等宽瀑布流布局
首先js 实现登录瀑布流原理
1: 通过定位的方式是我们实现瀑布流的最基本的原理,只要我们动态的设置它的top值、left值,就能让它排列。
注意: 图片的真实高度500(px) 真实宽度 300(px) 可能很高 比如我们规定在我们容器盒子中 图片盒子等宽 值为200(px), 我们需要手动去计算每个图片在我们容器中的高度, 300 / 500 = 200 / 图片盒子所在容器高度; 确保图片的宽/高的 比例正确。图片正确展示。
2:然后规定我们 在容器中 需要展示几列 column可以 手动规定,,也可以根据页面宽度去手动计算。这个根据情况 自行选择。 column = pageWidth / itemWidth;
如下图: 手动计算得到 column = 5
3: 我们需要一个 记录每行 所存图片盒子的高度的数组。 heightList: [ 100, 200, 400, 120, 150]。
在vue 中我们可以根据 column动态进行初始化。
data() {
return {
heightList: new Array(this.col).fill(0), // 如果定义col为 4 那么heightList[0, 0, 0, 0]
};
},
4: 然后我们开始 遍历我们接口返回的图片数组 list。进行动态计算每个图片盒子的left,top值
5:
for (let i = 0; i < list.length; i++) {
let obj = list[i];
if (/(.jpg|.png)$/.test(obj.url)) { // 判断是否是 图片
// 1- 等宽瀑布流 根据图片真实高度计算 当前等宽图片盒子 下图片的高度比例
obj.height = (this.width * obj.height) / obj.width;
obj.width = this.width;
// 2- 排列第二行 找到上一行所存高度数组中 高度最小的那一列的位置。 将第2行的第1个图片盒子放置在它的下方
let index = this.findMinimumIndex();
this.imageList.push({
...obj,
height: obj.height + "px",
width: this.width + "px",
left: index * (this.width + this.gutterWidth) + "px",
top: this.heightList[index] + "px" // 第二行第一个图片盒子 放在第一行高度数组中 高度最小的那个位置
});
// 当前高度最小列的高度 = 当前高度最小列的高度 + 间隙 + 下面图片盒子的高度 防止图片都叠在当前高度最小列下方
this.heightList[index] += obj.height + 60; // 第1行排列好之后,获取第1行所有图片盒子的高度 arr[h1,h2,h3] 后续----新高度赋值给数组
}
}
findMinimumIndex() { // 这个是获取数组中 最小值的索引方法
let minimum = Math.min(...this.heightList); // 获取数字 数组中当前最小值 [0,5,8] 那么为 0
return this.heightList.findIndex(item => minimum === item);
},
排列第二行:
1: 获取到刚刚数组中,高度最小的那一列,将第2行的第1个图片盒子放置在它的下方;
2: 此时的left值就是高度最小列的 index * (this.width + this.gutterWidth)上一列的宽度;top值就是:第1行高度最小列的高度(为了布局美观可以加上上下间隙gap)。
3: 记录下高度最小列的索引index,后面计算会用到;
4: 设置完成之后,会发现后面所有的图片都叠在这个高度最小列的下面,原因就是此时的最小列高度没有改变,应该加上下面图片的高度,得出一个新高度。
6: 改变最小列当前高度
重要:
6-1: 此时的这一列高度其实已经发生改变了,所以需要将新高度赋值给数组
6-2: 当前高度最小列的高度 = 当前高度最小列的高度 + 间隙 + 下面图片盒子的高度
参考文档: https://www.cnblogs.com/embrace-ly/p/10572523.html