Vue瀑布流布局

本文介绍了如何在Vue框架中实现瀑布流布局,强调了在Vue中减少DOM操作的重要性。通过绝对定位和onload事件处理图片加载后的布局调整,实现了一个动态响应窗口大小变化的瀑布流布局示例。示例代码包括了Vue实例、CSS样式和JavaScript方法,适用于展示图片内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虽然会写js的瀑布流布局,但是在Vue框架下使用,还是要稍作修改,毕竟要减少DOM操作。

原理依旧是 绝对定位+left+top

图片和文字还是有区别的,那就是渲染时间,所以我使用了onload,在图片渲染之后再进行瀑布流的布局

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
  <title>Vue 瀑布式布局</title>
</head>
<style>
  body,
  div,
  dl,
  dt,
  dd,
  ul,
  ol,
  li,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6,
  pre,
  code,
  form,
  fieldset,
  legend,
  input,
  button,
  textarea,
  p,
  blockquote,
  th,
  td {
    margin: 0;
    padding: 0;
  }

  .waterfall {
    position: relative;
  }

  .item {
    position: absolute;
    box-sizing: border-box;
    padding: 10px;
    transition: top, left .25s linear;
  }

  .item-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 10px;
    height: auto;
    font-size: 20px;
    color: #686868;
    box-sizing: border-box;
    border: 1px solid #ccc;
  }

  .clearfix {
    zoom: 1;
  }

  .clearfix::after {
    content: "";
    display: block;
    overflow: hidden;
    clear: both;
    height: 0;
  }

  img {
    height: 100%;
    width: 100%;
  }
</style>

<body>
  <div class="waterfall" id="app">
    <!--文本--->
    <!-- <div class="item" v-for="(item,index) in list" :key="index" :ref=`refValue${index}`> 
      <div class="item-content">
        {{item}}
      </div>
    </div> -->

    <!--图片-->
    <div class="item" v-for="(item,index) in list" :key="index" :ref=`refValue${index}`>
      <div class="item-content">
        <img :src="item" :alt="index" :title="index">
      </div>
    </div>
  </div>

</body>
<script>
  let app = new Vue({
    el: '#app',
    data() {
      return {
        list: [],
        imgList: [
          "./1-1.jpg",
          "./1-2.jpg",
          "./1-3.jpg",
          "./1-4.jpg",
          "./1-5.jpg",
          "./1-6.jpg",
          "./1-7.jpg",
          "./2-1.jpg",
          "./2-2.jpg",
          "./2-3.jpg",
          "./2-4.jpg",
          "./2-5.jpg",
          "./2-6.jpg",
          "./2-7.jpg",
        ],
        textList: [
          "1.三月到大理赏樱花不远不近,在部队那些日子被遗忘",
          "2.三月到大理赏樱花不远不近,才是最好的距离余生,请带上自己的阳光回忆,在部队那些日子被遗忘的花儿春光",
          "3.三月到大理赏樱花不远不近,才是最好的距离余生,请带上自己的阳光回忆",
          "4.三月到大理赏樱花不远不近",
          "5.三月到大理赏樱花不远不近,才是最好的距离余生,请带上自己的阳光回忆,在部队",
          "6.三月到大理赏樱花不远不近,才是最好的距离余生,请带上自己的",
          "7.三月到大理赏樱花不远不近,又近",
          "8.三月到大理赏樱花不远不近,才是最好的距离余生,请带上自己的阳光回忆遗忘的花儿春光",
          "9.三月到大理赏樱花不远不近,才是最好离余生,请带上自己的回忆",
        ]
      }
    },
    methods: {
      getBodyWidth() {
        return document.body.clientWidth || document.body.offsetWidth || document.body.scrollWidth;
      },
      getWidth(e) {
        return e.split('px')[0];
      },
      changePosition() {
        //列值
        let column = 3;
        //窗口可视宽度
        let width = this.getBodyWidth();
        //获取元素高度,用于下级元素top值
        let heightTopArray = [];

        for (let i = 0; i < this.list.length; i++) {

          //设置元素宽度
          let refName = 'refValue' + i;

          if (!this.$refs[refName][0]) {
            setTimeout(() => {
              this.changePosition();
            }, 200);
          };

          this.$refs[refName][0].style.width = width / column + 'px';

          /***设置top值**/
          /***设置left值**/
          /***第一行***/
          if (i < column) {
            this.$refs[refName][0].style.top = '0px';
            this.$refs[refName][0].style.left = this.getWidth(this.$refs[refName][0].style.width) * i + 'px';
            heightTopArray.push(this.$refs[refName][0].clientHeight);

            /***其他行***/
          } else {
            //余数==》横向索引
            let mod = i % column;

            this.$refs[refName][0].style.top = heightTopArray[mod] + 'px';
            //更新top值
            heightTopArray[mod] = heightTopArray[mod] + this.$refs[refName][0].clientHeight;

            this.$refs[refName][0].style.left = this.getWidth(this.$refs[refName][0].style.width) * mod + 'px';
          }

        }
      }

    },
    created() {
      this.list = this.imgList;
    },
    mounted() {
      window.onload = () => {
        this.changePosition();
      };

      window.onresize = () => {
        this.changePosition();
      }
    },
  })
</script>

</html>

其中的图片地址大家换成自己的本地图片地址就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值