瀑布流布局 vue

一种是使用纯 JavaScript 来实现,另一种是使用第三方库 Masonry.js

方案一:使用纯 JavaScript 实现

这种方法适用于想要完全控制瀑布流布局的情况。

步骤 1:HTML 结构

首先,在 HTML 中定义一个容器来存放瀑布流中的元素。

html 复制代码
<div id="waterfall">
  <!-- 瀑布流中的元素将动态插入到这里 -->
</div>
步骤 2:Vue 组件

接下来,创建一个 Vue 组件来处理瀑布流逻辑。

html 复制代码
<template>
  <div id="waterfall" ref="waterfall">
    <div v-for="(item, index) in items" :key="index" class="item" :style="{height: item.height + 'px'}">
      <img :src="item.src" :alt="item.alt" @load="onImgLoad(index)">
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        // 示例数据
        { src: 'image1.jpg', height: 200, alt: 'image1' },
        { src: 'image2.jpg', height: 300, alt: 'image2' },
        // 更多数据...
      ],
      columns: []
    };
  },
  methods: {
    onImgLoad(index) {
      const item = this.items[index];
      const shortestColumn = this.columns.reduce((minCol, currentCol) => 
        currentCol.height < minCol.height ? currentCol : minCol, this.columns[0]);
      shortestColumn.height += item.height;
      shortestColumn.items.push(item);
      this.reorderColumns();
    },
    reorderColumns() {
      this.columns.sort((a, b) => a.height - b.height);
    },
    init() {
      const waterfall = this.$refs.waterfall;
      this.columns = [];
      this.items.forEach((item, index) => {
        const column = this.columns.length > 0 ? this.columns[0] : { height: 0, items: [] };
        const div = document.createElement('div');
        div.className = 'column';
        const img = document.createElement('img');
        img.src = item.src;
        img.alt = item.alt;
        img.onload = () => {
          item.height = img.offsetHeight;
          column.height += img.offsetHeight;
          column.items.push(item);
          this.reorderColumns();
          this.$forceUpdate(); // 强制更新视图
        };
        div.appendChild(img);
        waterfall.appendChild(div);
      });
    }
  },
  mounted() {
    this.init();
  }
}
</script>

<style scoped>
#waterfall {
  column-count: 3; /* 初始列数 */
  column-gap: 10px;
  margin: 0 auto;
  max-width: 900px;
}

.item {
  break-inside: avoid;
  page-break-inside: avoid;
  overflow: hidden;
}
</style>

方案二:使用 Masonry.js

如果你希望使用一个成熟的库来简化瀑布流的实现,可以选择 Masonry.js。

步骤 1:安装 Masonry.js

首先,你需要安装 Masonry.js:

vbscript 复制代码
npm install masonry-layout
步骤 2:引入 Masonry.js

然后,在你的 Vue 组件中引入 Masonry.js。

html 复制代码
<template>
  <div id="masonry" class="masonry">
    <div v-for="item in items" :key="item.id" class="item">
      <img :src="item.src" :alt="item.alt">
    </div>
  </div>
</template>

<script>
import Masonry from 'masonry-layout';

export default {
  data() {
    return {
      items: [
        // 示例数据
        { id: 1, src: 'image1.jpg', alt: 'image1' },
        { id: 2, src: 'image2.jpg', alt: 'image2' },
        // 更多数据...
      ]
    };
  },
  mounted() {
    this.initMasonry();
  },
  methods: {
    initMasonry() {
      this.msnry = new Masonry('#masonry', {
        itemSelector: '.item',
        columnWidth: '.item'
      });
      this.items.forEach(item => {
        this.$nextTick(() => {
          this.msnry.appended(document.querySelector(`[data-id="${item.id}"]`));
          this.msnry.layout();
        });
      });
    }
  }
}
</script>

<style scoped>
.masonry {
  column-count: 3; /* 初始列数 */
  column-gap: 10px;
  margin: 0 auto;
  max-width: 900px;
}

.item {
  break-inside: avoid;
  page-break-inside: avoid;
  overflow: hidden;
}
</style>
相关推荐
用户7851278147018 小时前
从 0 到 1 落地淘宝商品 API 开发:手把手教你采集、分析与避坑(含完整可运行代码)
vue.js
威风的虫18 小时前
JavaScript中的axios
开发语言·javascript·ecmascript
比老马还六18 小时前
Blockly元组积木开发
前端
笨笨狗吞噬者18 小时前
【uniapp】小程序体积优化,JSON文件压缩
前端·微信小程序·uni-app
bot55566618 小时前
“企业微信iPad协议”静默 72 小时:一台被遗忘的测试机如何成为私域的逃生梯
javascript·面试
西洼工作室18 小时前
浏览器事件循环与内存管理可视化
前端·javascript·css·css3
xier12345619 小时前
高性能和高灵活度的react表格组件
前端
曦曜29219 小时前
富文本编辑器
javascript
你打不到我呢19 小时前
nestjs入门:上手数据库与prisma
前端
多啦C梦a19 小时前
React 实战:从 setInterval 到 useInterval,一次搞懂定时器 Hook(还能暂停!)
前端·javascript·react.js