天天看點

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毫秒的延時。

好了,我的瀑布流就這樣完成啦(▽)