假如说我们列表需要四列,html
就用四个ul
,并且平均分配宽度为25%
,然后每次渲染一条数据进去,就算一遍这个四个ul
的高度,那个ul
高最小,就把数据插入到那个ul
里面
<div class="source-list clearfix" id="sourceBox">
<ul data-id="0">
<li v-for="(item,index) in columnSourceList[0]" :key="index"></li>
</ul>
<ul data-id="1">
<li v-for="(item,index) in columnSourceList[1]" :key="index"></li>
</ul>
<ul data-id="2">
<li v-for="(item,index) in columnSourceList[2]" :key="index"></li>
</ul>
<ul data-id="3">
<li v-for="(item,index) in columnSourceList[3]" :key="index"></li>
</ul>
</div>
less设置,因为flex
布局,会默认子级等高布局,并且我们得算每个ul
的高度所以必须得设置align-items:flex-start;
.source-list{
display:flex;
align-items:flex-start;
justify-content:space-between;
ul{
width:25%;
max-width:300px;
}
li{
border:1px solid #f0f0f0;
border-radius:6px;
position:relative;
margin-bottom:20px;
}
}
js中,等我们请求完接口拿到数据之后,就去拿到四个ul
元素,并且开始算高度,排序之后给高度最低的ul
插入数据
data () {
return {
columnSourceList:[[],[],[],[]],//存放素材每一列的数据,共四列
}
},
mounted(){//mounted中可以获取到元素,created中获取不到
//添加滚动事件
window.onscroll=function (){
let height=document.body.scrollHeight;
let clientHeight=document.documentElement.clientHeight;
let scrollTop=document.documentElement.scrollTop || document.body.scrollTop;
if (clientHeight+scrollTop+50 > height){
this.getListData();
}
};
this.getListData();
},
methods:{
async getListData(){//获取素材列表
let {data}=await getListApi();//请求接口
this.sourceList=data.list;
//请求玩接口拿到数据后获取四个ul放到数组中
const aUl=document.querySelectorAll("#sourceBox>ul");
for(let i=0;i<aUl.length;i++){
this.elArr.push(aUl[i]);
}
this.pushData();
},
pushData(){//给高度最低的ul放入数据
let item=this.sourceList.shift();
if(item){//如果有数据才高度排序插入数据
this.elArr.sort((a,b)=>{//给ul的高度排序,由小到大
return a.offsetHeight-b.offsetHeight
});
//获取这个高度最小的ul上面的index,知道是往那个ul上插入数据
let index=Number.parseInt(this.elArr[0].dataset.id);
//push完数据,继续调用
this.columnSourceList[index].push(item);
this.$nextTick(()=>{
this.pushData();
});
}
}
}
之所以用this.sourceList.shift()
方法和递归来获取第一条数据并插入,而不用forEach
循环来获取数据插入ul
,是因为forEach
无法满足获取ul
的高度,在forEach
中获取的高度都是一样的,因为vue中插入数据然后渲染也是需要时间的,所以在forEach
获取ul
的高度会一直是0
this.sourceList.forEach(item=>{
this.elArr.sort((a,b)=>{
return a.offsetHeight-b.offsetHeight
});
let index=Number.parseInt(this.elArr[0].dataset.id);
console.log(this.elArr[0].offsetHeight)//0
this.columnSourceList[index].push(item);
})
网友评论