美文网首页
vue中瀑布流布局

vue中瀑布流布局

作者: keknei | 来源:发表于2022-08-16 17:14 被阅读0次

    假如说我们列表需要四列,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);
          })
    

    相关文章

      网友评论

          本文标题:vue中瀑布流布局

          本文链接:https://www.haomeiwen.com/subject/lrfdgrtx.html