将瀑布流抽成了vue的一个组件
<template>
<div class="wrapper" :class="isHidden?'isHidden':''">
<div id="sortable">
<div class="card" v-for="item in showList">
<div class="card_picture_warp">
// 这里需要@load判断图片是否已加载完 由于图片加载的过慢,所以有可能在排列后,图片才显示出来,导致排列错乱
<img class="card__picture" :src="item.thumb" alt="" @load="loadImage">
</div>
<div class="user_info"></div>
...
</div>
</div>
</div>
</template>
<script>
import {Indicator} from 'mint-ui';
export default {
//接收父组件传入的数据
props: {
showList: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
isHidden: true, //为瀑布流排列好后再进行展示 可以对用户更加友好
isLoad: false,
maxH: 0,
loadNum: 0
}
},
watch: {
showList: {
handler() {
this.showSortable()
}
}
},
methods: {
// isLoad 用来判断 是否所有图片都已经加载完毕
loadImage() {
this.loadNum++
if (this.loadNum === this.showList.length) {
this.isLoad = true
this.loadNum = 0
}
},
showSortable() {
Indicator.open('加载中...');
// 初始化状态
this.isHidden = true
if(this.showList.length !==0) {
// 重置外容器的高度
if (document.getElementsByClassName('wrapper')[0]) {
document.getElementsByClassName('wrapper')[0].style.height = 'auto'
}
const that = this
let bbl = setInterval(function () {
if (that.isLoad) {
// 进行瀑布流排序
that.waterFall()
// 改变容器的高度 that.maxH 在waterFall()中获取
document.getElementsByClassName('wrapper')[0].style.height = that.maxH + 'px'
that.isHidden = false
that.isLoad = false
Indicator.close();
clearInterval(bbl)
}
}, 100)
}
},
waterFall() {
let box = document.getElementById('sortable');
let items = box.children;
// 定义每一列之间的间隙 为10像素
let gap = 10; // 安卓一般为ios的两倍,所以需要判断
const u = navigator.userAgent
const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 // android终端
const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
if (isAndroid) {
gap = 10
} else if (isiOS) {
gap = 20
}
let itemWidth = items[0].offsetWidth;
let leftWidth = items[0].offsetWidth * 2 * 0.03
// 1- 确定列数
let columns = 2;
let arr = [];
for (let i = 0; i < items.length; i++) {
if (i < columns) {
// 2- 确定第一行
items[i].style.top = 2 + 'vw';
items[i].style.left = (itemWidth + gap) * i + leftWidth + 'px';
arr.push(items[i].offsetHeight);
} else {
// 其他行
// 3- 找到数组中最小高度 和 它的索引
let minHeight = arr[0];
let index = 0;
for (let j in arr) {
if (minHeight > arr[j]) {
minHeight = arr[j];
index = j;
}
}
// 4- 设置下一行的第一个盒子位置
// top值就是最小列的高度 + gap
items[i].style.top = arr[index] + gap + 20 + 'px';
// left值就是最小列距离左边的距离
items[i].style.left = items[index].offsetLeft + 'px';
// 5- 修改最小列的高度
// 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
arr[index] = arr[index] + items[i].offsetHeight + gap;
// 获取整个容器的整体高度
this.maxH = arr[index]
}
}
}
}
}
</script>