天天看点

vue实现瀑布流

最近项目要加一个瀑布流的页面,像这样:

vue实现瀑布流

一开始我想着直接写一个容器,容器的css属性加上column-width: 50%;和column-count: 2;为了避免在主体框中插入任何中断,需要向容器内子元素的css加上一个break-inside: avoid;但是这种写法有一个问题就是排列顺序是左边显示前一半,右边显示后一半,像这样:

vue实现瀑布流

而我需要的是那种每条数据根据左右区域的高度来判断这条数据是加载到左边还是右边的那种,像这样:

vue实现瀑布流

于是用纯css实现的想法就放弃了。

后来我想到分成左右两个列表去渲染:

首先在data里申明四个变量:

data:{
	leftlist:[],
	rightlist:[],
	leftHeight:0,
	rightHeight:0,
}
           

然后给左右两个列表分别加上 ref="left"和 ref=“right”

获取到列表数据后我用的是递归的方式向leftlist和rightlist内添加的数据

向列表添加数据函数如下:

adddata(n,length,data){
            this.leftHeight=this.$refs.left.offsetHeight;
            this.rightHeight=this.$refs.right.offsetHeight;
            if(this.leftHeight<=this.rightHeight){
              this.leftlist.push(data[n]);
              this.$nextTick(function(){
                setTimeout(function(){
                  if(++n<length){
                    vm.addblock(n,length,data);
                  }
                },100)
              })
            }else{
              this.rightlist.push(data[n]);
              this.$nextTick(function(){
                setTimeout(function(){
                  if(++n<length){
                    vm.addblock(n,length,data);
                  }
                },100)
              })
            }
          }
           

这里会发现我在$nextTick里加了一个定时器,原因是DOM挂载和渲染都已完成后,每个数据的图片是未必展示完整的,这会影响到左右列表的高度也就间接影响到了后一条数据的添加位置,目前没想到更好的办法我就加了一个100毫秒的延时。

好了,我的瀑布流就这样完成啦(▽)