vue实现瀑布流的方式

27 篇文章 4 订阅
我们知道瀑布流是等宽不等高的,下边我们使用两种方式实现瀑布流
css3的column布局 column-count: column-gap
  • template
  <template>
  <div id="app">
    <ul>
      <li
        ref='waterfallItem'
        v-for="(item,index) in waterfallArr"
        :key="index"
      >
        <img :src="item.img"> 第{{index+1}}张
        <span>原价 {{item.price}}</span>
        </li>
    </ul>
  </div>
</template>
  • javacript
<script>
export default {
  data() {
    return {
      waterfallArr: [
        {
          id: 1,
          img: require("./assets/images/1.jpg"),
          price: "50",
        },
        {
          id: 2,
          img: require("./assets/images/2.jpg"),
          price: "50",
        },
        {
          id: 3,
          img: require("./assets/images/3.jpg"),
          price: "50",
        },
        {
          id: 4,
          img: require("./assets/images/4.jpg"),
          price: "50",
        },
        {
          id: 5,
          img: require("./assets/images/5.jpg"),
          price: "50",
        },
        {
          id: 6,
          img: require("./assets/images/6.jpg"),
          price: "50",
        },
      ],
    };
  },
  mounted() {},
  methods: { },
};
</script>
  • css
 
<style lang="scss" scoped>
#app {
  width: 750px;
  height: 100vh;
  background-color: #0f0;
  color: #333;
  text-align: center;
  font-size: 20px;
  ul {
    width: 750px;
    height: 100%;
    box-sizing: border-box;
    background-color: #fff;
    column-count: 2;
    column-gap: 20px;
    padding: 20px;
    li {
      height: auto;
      font-size: 14px;
      box-sizing: border-box;
      margin: 0 0 10px 0;
      overflow: hidden;
      img {
        width: 100%;
        display: block;
        height: auto;
      }
      span {
        text-decoration: line-through;
        line-height: 2;
        margin-left: 10px;
      }
    }
  }
}
</style>

效果图如下,我们发现这个图片第一张第二张都是竖着排列的,不是我们想要的结果

image.png

第二种使用grid布局

  • template
  <template>
  <div id="app">
    <ul>
      <li
        ref='waterfallItem'
        v-for="(item,index) in waterfallArr"
        :key="index"
      >
        <img :src="item.img"> 第{{index+1}}张
        <span>原价 {{item.price}}</span>
        </li>
    </ul>
  </div>
</template>
  • javacript
<script>
export default {
  data() {
    return {
      waterfallArr: [
        {
          id: 1,
          img: require("./assets/images/1.jpg"),
          price: "50",
        },
        {
          id: 2,
          img: require("./assets/images/2.jpg"),
          price: "50",
        },
        {
          id: 3,
          img: require("./assets/images/3.jpg"),
          price: "50",
        },
        {
          id: 4,
          img: require("./assets/images/4.jpg"),
          price: "50",
        },
        {
          id: 5,
          img: require("./assets/images/5.jpg"),
          price: "50",
        },
        {
          id: 6,
          img: require("./assets/images/6.jpg"),
          price: "50",
        },
      ],
    };
  },
  mounted() {},
  methods: { },
};
</script>
  • css
 
<style lang="scss" scoped>
#app {
  width: 750px;
  height: 100vh;
  background-color: #0f0;
  color: #333;
  text-align: center;
  font-size: 20px;
  ul {
  width: 750px;
    height: 100%;
    box-sizing: border-box;
    background-color: #fff;
    display: grid;
    grid-gap: 10px;
    /* 可以看到,网格大小,占据位置是需要提前设定的 */
    grid-template-columns: repeat(2, 1fr);
    li {
      height: auto;
      font-size: 14px;
      box-sizing: border-box;
      margin: 0 0 10px 0;
      overflow: hidden;
      img {
        width: 100%;
        display: block;
        height: auto;
      }
      span {
        text-decoration: line-through;
        line-height: 2;
        margin-left: 10px;
      }
    }
  }
}
</style>

效果图如下,很显然这种等宽和同行等高的不是我们想要的瀑布流,优点类似于flex布局了

image.png

第三种使用js动态生成

  • template
  <template>
  <div id="app">
    <ul>
      <li
        ref='waterfallItem'
        v-for="(item,index) in waterfallArr"
        :key="index"
      >
        <img :src="item.img"> 第{{index+1}}张
        <span>原价 {{item.price}}</span>
        </li>
    </ul>
  </div>
</template>
  • javacript
<script>
export default {
  data() {
    return {
      waterfallArr: [
        {
          id: 1,
          img: require("./assets/images/1.jpg"),
          price: "50",
        },
        {
          id: 2,
          img: require("./assets/images/2.jpg"),
          price: "50",
        },
        {
          id: 3,
          img: require("./assets/images/3.jpg"),
          price: "50",
        },
        {
          id: 4,
          img: require("./assets/images/4.jpg"),
          price: "50",
        },
        {
          id: 5,
          img: require("./assets/images/5.jpg"),
          price: "50",
        },
        {
          id: 6,
          img: require("./assets/images/6.jpg"),
          price: "50",
        },
        {
          id: 7,
          img: require("./assets/images/5.jpg"),
          price: "50",
        },
        {
          id: 8,
          img: require("./assets/images/6.jpg"),
          price: "50",
        },
      ],
      array: [] //定义空数组存储元素高度
    };
  },
  mounted() {
   setTimeout(() => { // 防止图片高度没有加载出来
      this.getWaterfall();
   },100)
  },
  methods: {
    getWaterfall() {
      let columns = 2; //定义布局的列数为2
      let item = this.$refs.waterfallItem; //获取每个子元素的DOM
      console.log("item",item)
      for (let i = 0; i < item.length; i++) {
        //遍历整个子元素的DOM集合
        if (i < columns) {
          //小于columns的子元素作为第一行
          item[i].style.top = 20 + 'px';
          item[i].style.left = item[0].clientWidth * i + "px";
          console.log("offsetWidth", item[0].clientHeight)
          this.array.push(item[i].clientHeight); //遍历结束时,数组this.array保存的是第一行子元素的元素高度
          console.log("this.array",this.array)
        } else {
          //大于等于columns的子元素将作其他行
          let minHeight = Math.min(...this.array); //  找到第一列的最小高度
          let index = this.array.findIndex(item => item === minHeight) // 找到最小高度的索引
          //设置当前子元素项的位置
          item[i].style.top = this.array[index] +25+ "px"; 
          item[i].style.left = item[index].offsetLeft + "px";
          //重新定义数组最小项的高度 进行累加
          this.array[index]+= item[i].clientHeight
          console.log("this.array[index]",this.array[index])
        }
      }
    },
  },
};
</script>
  • css
 
<style lang="scss" scoped>
#app {
  width: 750px;
  height: 100vh;
  background-color: #0f0;
  color: #333;
  text-align: center;
  font-size: 20px;
  ul {
    width: 750px;
    height: 100%;
    list-style: none;
    box-sizing: border-box;
    background-color: #fff;
    overflow: hidden;
    li {
      width: 50%;
      height: auto;
      padding: 10px;
      font-size: 14px;
      position: absolute;
      box-sizing: border-box;
      margin: 0 0 10px 0;
      overflow: hidden;
      img {
        width: 100%;
        display: block;
        height: auto;
      }
      span {
        text-decoration: line-through;
        line-height: 2;
        margin-left: 10px;
      }
    }
  }
}
</style>


效果图如下,很明显这个才是我们想要的结果

image.png

第四种 flex布局实现瀑布流
<template>
  <view class="list">
    <view class='list-half'>
      <view class="item" v-for="(item,index) in listData" :key="index" v-if="index%2 !== 0">
        <image   class='card' :src="item.img" style="width: 346rpx;" mode="widthFix"></image>
      </view>
    </view>
    <view class='list-half'>
        <view class="item" v-for="(item,index) in listData" :key="index" v-if="index%2 == 0">
          <image class='card' :src="item.img" style="width: 346rpx;" mode="widthFix"></image>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
  export default {
    components: {
    
    },
    data() {
      return {
        listData: [
          {
            id: 1,
            img: "../../static/images/P_00.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_01.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_02.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_03.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_04.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_05.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_06.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_07.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_08.jpg"
          },
          {
            id: 1,
            img: "../../static/images/P_09.jpg"
          },
          {
            id: 1,
            img: "../../static/Pimages/_010.jpg"
          },
        ]
      }
    },
    methods: {
      
    }
  }
</script>

<style>
  .list {
    padding: 20rpx;
    display: flex;
    justify-content: space-between;
  }
  .list .list-half {
    width: 346rpx;
    height: 100%;
    box-sizing: border-box;
  }
  image {
    height: 100%;
  }
  .list-half .card {
    border-radius: 20rpx;
    overflow: hidden;
    margin-bottom: 30rpx;
  }
</style>

展示如下

在这里插入图片描述

  • 1
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lxslxskxs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值