vue中瀑布流布局

假如说我们列表需要四列,html就用四个ul,并且平均分配宽度为25%,然后每次渲染一条数据进去,就算一遍这个四个ul的高度,那个ul高最小,就把数据插入到那个ul里面

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{//给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);
      })

你可能感兴趣的:(vue中瀑布流布局)