学习笔记05 - css布局 瀑布流

需求:实现如图所示的瀑布流布局(左右item宽度相同,但高度不同,形成高度差布局)

分析:

1. 每个item由一张图片和下方的文字构成

2. 通过改变图片的高度,实现整体item的高度差

 

实现方式:

1.获取列表

2. 遍历,随机生成一定高度范围内的数组,将"height:xxxpx;"的style样式,给每一个img标签

3. 声明两个变量:左侧总高度,右侧总高度

4. 遍历,if左侧总高>=右侧总高,item应分配在左侧,否则,item分配在右侧

5. item样式均设置为absolute,分在左侧是left:0,右侧为right:0,top值通过计算获得

6. 第一个item:"left:0;top:0;",更新左侧总高 += item1.offsetHeight + 两个item上下间隔距离 +‘px’

   第二个item:"right:0;top:0;",更新右侧总高 += item2.offsetHeight + 两个item上下间隔距离 +‘px’

   第三个item:"left:0;top: 左侧总高;",更新左侧总高 += item3.offsetHeight + 两个item上下间隔距离 +‘px’

  以此类推...

7. 所有item的样式,存放在数组中,用于布局

参考代码

<template>
  <div class="goods">
    <div class="goods-item" v-for="(item,index) in goodsData" :key="index" :style="goodsStyles[index]">
      <img :src="item.img" :style="imgHeightStyles[index]" >
      <div class="goods-item-desc">
        <p class="goods-item-desc-title text-line-2" >{{item.name}}</p>
        <div class="goods-item-desc-detail">
          <p  class="goods-item-desc-detail-price">¥ {{item.price}}</p>
          <p  class="goods-item-desc-detail-stock">销量: {{item.volume}}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'goods',
  data () {
    return {
      MIN_IMG_HEIGHT: 178,
      MAX_IMG_HEIGHT: 230,
      goodsData: [],
      imgHeightStyles: [],
      goodsStyles: [],
      leftHeightTotal: 0,
      rightHeightTotal: 0
    }
  },
  mounted () {
    this.initData()
  },
  methods: {
    // 初始化商品列表
    initData () {
      this.$http.get('/goods').then(data => {
        this.goodsData = data.list
        console.log(this.goodsData)
        // 生成图片高度数组
        this.getImgHeights()
        // 排列
        this.initLayout()
      })
    },
    getImgHeights () {
      this.goodsData.forEach(element => {
        this.imgHeightStyles.push({
          height: this.imgHeight() + 'px'
        })
      })
      console.log(this.imgHeightStyles)
    },
    /**
     * 返回随机的图片高度
     */
    imgHeight: function () {
      const result = Math.floor(Math.random() * (this.MAX_IMG_HEIGHT - this.MIN_IMG_HEIGHT) + this.MIN_IMG_HEIGHT)
      return result
    },
    initLayout () {
      // DOM更新后才能设置布局
      this.$nextTick(() => {
        var elementList = document.getElementsByClassName('goods-item')
        console.log(elementList)

        elementList.forEach(ele => {
          console.log(ele)
          // 1.判断排列在左侧/右侧
          if (this.leftHeightTotal <= this.rightHeightTotal) {
          // 左侧
            this.goodsStyles.push('left:0px;top:' + this.leftHeightTotal + 'px;')
            // 2.获取item的高度
            this.leftHeightTotal += ele.offsetHeight
            // 3.加上margin的距离,更新总体高度
            this.leftHeightTotal += 12
          } else {
          // 右侧
            this.goodsStyles.push('right:0px;top:' + this.rightHeightTotal + 'px;')
            this.rightHeightTotal += ele.offsetHeight
            this.rightHeightTotal += 12
          }
        })
      })
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@css/style.scss';
.text-line-2{
  overflow : hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.goods{
  position: relative;
  margin:$marginSize;
}
.goods-item{
  position: absolute;

  width: 49%;
  padding: px2rem(5);
  background-color: #fff;
  box-sizing: border-box;
  border-radius: $radiusSize;

  img{
    width:100%;
  }
  &-desc{
     width: 100%;
     font-size: $infoSize;
     overflow: hidden;
     &-detail{
       display: flex;
       align-items: center;
       justify-content: space-between;
       margin-top: px2rem(5);
       &-price{
         color: red;
       }
       &-stock{
         color: silver;
         text-align: right;;
       }
     }
  }
}
</style>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值