乐趣区

关于前端:Vue项目的瀑布流部分代码分析

<!--
 * @Author: yang
 * @Date: 2020-10-18 15:58:57
 * @LastEditors: yang
 * @LastEditTime: 2020-10-23 17:27:59
 * @FilePath: \gl\src\component\index\receive.vue
-->
<template>
  <div class="about">
    <p> 瀑布流, 点击图片可删除一个 </p>
    <div class="page">
      <div
        class="content"
        v-for="(item, index) in list"
        :key="item.id"
        :style="{
          width: waterfallW + 'px',
          height: item.imgH + 'px',
          left: item.left + 'px',
          top: item.top + 'px',
        }"ref="col"@click="clickMe(index)"
      >
        <img :src="item.image" alt="" />
      </div>
    </div>
  </div>
</template>

<script>

export default {data() {
     return {
      list: [
      {
      image:
        'http://img-agc.iqianggou.com/0a62fca1eeab88e894b93539c35446ec!180x180',
      imgH: 122,
      title: '题目只有 1 行哦长砍',
      desc: 'Bon Cake(徐家汇店) 这家店不要条好吃啊',
      praiseNum: 322,
      top: 0,
      left: 0,
      itemH: 0,
    },
    {
      image:
        'http://img-agc.iqianggou.com/0a62fca1eeab88e894b93539c35446ec!180x180',
      imgH: 334,
      title: '题目只有 1 行哦长砍题目只有 1 行哦长砍题目只有 1 行哦长砍',
      desc:
        'Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店',
      praiseNum: 32232,
      top: 0,
      left: 0,
      itemH: 0,
    },
    {
      image:
        'http://img-agc.iqianggou.com/0a62fca1eeab88e894b93539c35446ec!180x180',
      imgH: 173,
      title: '题目只有 1 行哦长砍',
      desc:
        'Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店',
      praiseNum: 32,
      top: 0,
      left: 0,
      itemH: 0,
    },
    {
      image:
        'http://img-agc.iqianggou.com/0a62fca1eeab88e894b93539c35446ec!180x180',
      imgH: 225,
      title: '题目只有 1 行哦长砍',
      desc: 'Bon Cake(徐家汇店) 这家店',
      praiseNum: 32,
      top: 0,
      left: 0,
      itemH: 0,
    },
    {
      image:
        'http://img-agc.iqianggou.com/0a62fca1eeab88e894b93539c35446ec!180x180',
      imgH: 89,
      title: '题目只有 1 行哦长砍',
      desc:
        'Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店 Bon Cake(徐家汇店) 这家店',
      praiseNum: 32,
      top: 0,
      left: 0,
      itemH: 0,
    },
    {
      image:
        'http://img-agc.iqianggou.com/0a62fca1eeab88e894b93539c35446ec!180x180',
      imgH: 112,
      title: '题目只有 1 行哦长砍',
      desc: 'Bon Cake(徐家汇店) 这家店',
      praiseNum: 32,
      top: 0,
      left: 0,
      itemH: 0,
     }
      ],
       initLeft:'',
       waterfallW:'',
       screenWidth:document.clientWidth,// 屏幕宽度
        gap:10,// 图片之间的间距
      leftH : 0,// 左侧高度
      rightH:0// 右侧高度
     }
   },
   created () {this.waterfallW = (this.screenWidth-30)/2;
     this.initLeft = (this.screenWidth - this.waterfallW)/2;
   },
   mounted () {
     const nodeList = this.$refs.col;
     this.doSort(nodeList)
   },
   methods: {
    //  排序
     doSort(nodeList) {for(let i =0;i<nodeList.length;i++){nodeList[i].style.position = 'absolute';
         const domHeight = nodeList[i].clientHeight; // 获取图片的高度
         let top,left,itemH;
        //  排列数据的模式高的在左侧, 低矮的在右侧
         if(this.leftH>this.rightH){// 如果左侧的比右侧图片高
           left = this.gap * 2 + this.waterfallW;  // 右侧的 left
           top = this.rightH + this.gap;// 图片高度加间距
           itemH = domHeight;
           this.rightH += this.gap + domHeight;// 右侧的整体高度
         }else{
           left = this.gap;
           top = this.leftH + this.gap;// 左侧的 top
           itemH = domHeight;// 图片的高度
           this.leftH += this.gap + domHeight;// 左侧的高度
         }
         this.list[i].top = top;
         this.list[i].left = left;
         this.list[i].itemH = itemH;
         this.list[i].itemW = this.waterfallW;
       }
     },
     clickMe(index){const renderedList = this.list.slice(0,index)// 失去索引前的数据
       const afreshRenderList = this.list.slice(index+1)// 失去点击索引后的数据
       if(this.list[index].left>this.gap){// 就是右侧的图片
         this.rightH = this.list[index].top - this.gap // 去除一个间距, 被删除数据列无需重排数据的高度
         this.leftH = this.checkHeight(renderedList,'left')
       }else{this.rightH = this.checkHeight(renderedList,'right')
         this.leftH = this.list[index].top-this.gap// 去除一个间距, 被删除数据列无需重排数据的高度
       }
       const newList = this.restartSort(afreshRenderList)
       this.list = [...renderedList,...newList]
     },
     //  查找不须要重新排列的数据中非被删除列的高度
     checkHeight(list,col){
       let needHeight = 0;
       for(let i=0;i<list.length;i++){if(col == 'left'&& list[i].left == this.gap&&list[i].top>needHeight){needHeight = list[i].top+list[i].itemH
         }else if(col = 'right'&&
           list[i].left>this.gap&&
           list[i].top>needHeight){needHeight = list[i].top + list[i].itemH;
           }
       }
       return needHeight;
     },
     // 重新排列列表中被删除数据之后的所有数据
     restartSort(list){// 重排之后 长的在右边,短的在左边
       const newList = list
       newList.forEach((item)=>{if(this.leftH>this.rightH){
           item.left = this.gap*2+item.itemW // 右侧的 left
           item.top = this.rightH + this.gap // 右侧的 top
           this.rightH +=this.gap+item.itemH// 右侧的高度
         }else{
           item.left = this.gap // 左侧的 left
           item.top = this.leftH + this.gap // 左侧的 top
           this.leftH += this.gap+item.itemH
         }
       })
       return newList;
     }
   },

}
</script>

<style lang="scss" scoped>
.page {
  position: relative;
  width: 100%;
  height: 100%;
}
.content {
  position: fixed;
  top: 100%;
  img {
    display: block;
    width: 100%;
    height: 100%;
  }
}
</style>
退出移动版