瀑布流布局 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>
相关推荐
Vicky&James12 分钟前
WPF到Web的无缝过渡:英雄联盟客户端项目OpenSilver迁移实战
前端·wpf
m0_7482336416 分钟前
RabbitMQ 进阶
android·前端·后端
不想有bug的小菜鸟24 分钟前
vue3使用iframe全屏展示pdf效果
前端·pdf
m0_7482386325 分钟前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
u01005596026 分钟前
前端代理,解决跨域问题讲解
前端
quitv31 分钟前
react脚手架配置别名
前端·javascript·react.js
m0_5287238139 分钟前
前端如何进行性能优化
前端·性能优化
化作繁星41 分钟前
在 Vue 3 中,如何缓存和复用动态组件
前端·vue.js·缓存
一粒沙-1 小时前
iOS 将GIF图分享至微信
前端·ios
graywen1 小时前
从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
前端