vue实现简单的瀑布流布局

<template>
  <div class="waterfull">
    <h2>瀑布流布局</h2>
    <div class="v-waterfall-content" id="v-waterfall">
      <div
        v-for="(img, index) in waterfallList"
        :key="index"
        class="v-waterfall-item"
        :style="{
          top: img.top + 'px',
          left: img.left + 'px',
          width: waterfallImgWidth + 'px',
          height: img.height,
        }"
      >
        <img :src="img.src" alt="" />
        说明文字
        <p style="font-size: small; color: #666; margin: 4px">
          {{ img.title }}
        </p>
        <p
          style="
            font-size: x-small;
            color: #9e9e9e;
            margin: 4px;
            padding-bottom: 6px;
          "
        >
          {{ img.info }}
        </p>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
/* eslint-disable */
export default {
  name: "v-waterfall",
  data () {
    return {
      waterfallList: [],
      imgArr: [
        require('../assets/err.png'),
        require('../assets/img/1.jpg'),
        require('../assets/img/2.jpeg'),
        require('../assets/img/3.jpg'),
        require('../assets/img/4.jpg'),
        require('../assets/img/5.jpg'),
        require('../assets/img/6.jpg'),
        require('../assets/img/7.jpg'),
        require('../assets/img/8.jpg'),
        require('../assets/img/9.jpg'),
        require('../assets/img/10.jpeg'),
        require('../assets/img/11.jpeg'),
        require('../assets/img/12.jpg'),
        require('../assets/err.png'),
        require('../assets/img/1.jpg'),
        require('../assets/img/2.jpeg'),
        require('../assets/img/3.jpg'),
        require('../assets/img/4.jpg'),
        require('../assets/img/5.jpg'),
        require('../assets/img/6.jpg'),
        require('../assets/img/7.jpg'),
        require('../assets/img/8.jpg'),
        require('../assets/img/9.jpg'),
        require('../assets/img/10.jpeg'),
        require('../assets/img/11.jpeg'),
        require('../assets/img/12.jpg'),
        require('../assets/err.png'),
        require('../assets/img/1.jpg'),
        require('../assets/img/2.jpeg'),
        require('../assets/img/3.jpg'),
        require('../assets/img/4.jpg'),
        require('../assets/img/5.jpg'),
        require('../assets/img/6.jpg'),
        require('../assets/img/7.jpg'),
        require('../assets/img/8.jpg'),
        require('../assets/img/9.jpg'),
        require('../assets/img/10.jpeg'),
        require('../assets/img/11.jpeg'),
        require('../assets/img/12.jpg'),
        require('../assets/err.png'),
        require('../assets/img/1.jpg'),
        require('../assets/img/2.jpeg'),
        require('../assets/img/3.jpg'),
        require('../assets/img/4.jpg'),
        require('../assets/img/5.jpg'),
        require('../assets/img/6.jpg'),
        require('../assets/img/7.jpg'),
        require('../assets/img/8.jpg'),
        require('../assets/img/9.jpg'),
        require('../assets/img/10.jpeg'),
        require('../assets/img/11.jpeg'),
        require('../assets/img/12.jpg')
      ],
      // waterfallImgWidth: 100,
      waterfallImgWidth: 200,// 每个盒子的宽度
      waterfallImgCol: 5,// 瀑布流的列数
      // waterfallImgCol: 3,// 瀑布流的列数
      waterfallImgRight: 10,// 每个盒子的右padding
      waterfallImgBottom: 10,// 每个盒子的下padding
      waterfallDeviationHeight: [],
      imgList: []
    }
  },
  created () {
    axios.get('/data.json', {

    })
      .then(function (res) {
        this.imgArr = res
      })
      .catch(function (error) {
      })
    // 触发入口
    for (let i = 0; i < this.imgArr.length; i++) {
      // this.imgList.push(this.imgArr[Math.round(Math.random() * 8)]);// 图片随机显示
      this.imgList.push(this.imgArr[i]);
    }
  },
  mounted () {
    this.calculationWidth();
  },
  methods: {
    //计算每个图片的宽度或者是列数
    calculationWidth () {
      let domWidth = document.getElementById("v-waterfall").offsetWidth;
      if (!this.waterfallImgWidth && this.waterfallImgCol) {
        this.waterfallImgWidth = (domWidth - this.waterfallImgRight * this.waterfallImgCol) / this.waterfallImgCol;
      } else if (this.waterfallImgWidth && !this.waterfallImgCol) {
        this.waterfallImgCol = Math.floor(domWidth / (this.waterfallImgWidth + this.waterfallImgRight))
      }
      //初始化偏移高度数组
      this.waterfallDeviationHeight = new Array(this.waterfallImgCol);
      for (let i = 0; i < this.waterfallDeviationHeight.length; i++) {
        this.waterfallDeviationHeight[i] = 0;
      }
      this.imgPreloading()
    },
    //图片预加载
    imgPreloading () {
      for (let i = 0; i < this.imgList.length; i++) {
        let aImg = new Image();
        aImg.src = this.imgList[i];
        aImg.onload = aImg.onerror = (e) => {
          let imgData = {};
          imgData.height = this.waterfallImgWidth / aImg.width * aImg.height;
          imgData.src = this.imgList[i];
          imgData.title = '标题';// 说明文字(也可以自己写数组,或者封装json数据,都可以,但是前提是你会相关操作,这里不赘述)
          imgData.info = '详情说明:啦啦啦啦啦';// 说明文字
          this.waterfallList.push(imgData);
          this.rankImg(imgData);
        }
      }

    },
    //瀑布流布局
    rankImg (imgData) {
      let {
        waterfallImgWidth,
        waterfallImgRight,
        waterfallImgBottom,
        waterfallDeviationHeight,
        waterfallImgCol
      } = this;
      let minIndex = this.filterMin();
      imgData.top = waterfallDeviationHeight[minIndex];
      imgData.left = minIndex * (waterfallImgRight + waterfallImgWidth);
      // waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;// 不加文字的盒子高度
      waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom + 56;// 加了文字的盒子高度,留出文字的地方(这里设置56px)
      console.log(this.waterfallList);
    },
    /**
     * 找到最短的列并返回下标
     * @returns {number} 下标
     */
    filterMin () {
      const min = Math.min.apply(null, this.waterfallDeviationHeight);
      return this.waterfallDeviationHeight.indexOf(min);
    }
  }
}
</script>

<style scoped>
.waterfull {
  width: 1050px;
  padding: 0 10px;
  margin: 0 auto;
  background: #000;
}
.v-waterfall-content {
  /* 主要 */
  width: 100%;
  /* height: 100vh; */
  position: relative;
  /* 次要:设置滚动条,要求固定高度 */
}

.v-waterfall-item {
  /* 主要 */
  float: left;
  position: absolute;
}

.v-waterfall-item img {
  /* 主要 */
  /* width: auto;height: auto; */
  width: 100%;
  height: auto;
  /* 次要 */
  border-radius: 6px;
}
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值