HTML中的瀑布流masonry在Vue中应用

瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站基本为这类风格。

img

可以说作为图片的一种展示风格,是非常的好看了,那么在HTML中怎么进行实现呢?

纯CSS实现

https://www.bilibili.com/video/BV1xa4y147JP?t=164

好吧,我就是看了这个视频后,才知道了原来这种排版叫做瀑布流,如果想要实现简单的瀑布流,根据这个视频中提供的思路,直接用CSS加上几行代码就能轻松实现瀑布流。所以这里就不再赘述,直接下一项。

masonry

既然有现成的,为什么还要自己写呢,现在主要讲一讲如何在Vue中使用masonry。

引入

引入的方式有两种,一种通过CDN引入

<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.js"></script>
<!-- or -->
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

一种是通过包管理的方式引入,即我们平时用的Vue,react框架,一般都是通过这种方式进行引入。

npm: npm install masonry-layout --save

Bower: bower install masonry-layout --save

使用

先将HTML结构创建出来:

<div class="grid">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  ...
</div>

注:

  • .grid即是所有图片的容器
  • .grid-item是单张图片的容器

创建后,就开始准备引入js

1、通过jQuery引入

$('.grid').masonry({
  // options...
  itemSelector: '.grid-item',
  columnWidth: 200
});

2、普通方式引入(Vue就是这样引入)

import Masonry from "masonry-layout"; // Vue项目的引入方式

updated() {
  var grid = document.querySelector(".grid");
  var msnry = new Masonry(grid, {
    // options...
    itemSelector: ".grid-item",
    columnWidth: 300,
  });
}

经过多次测试,发现放在updated中是最保险的,最开始我将初始化放在了mounted这个生命周期里面,虽然静态的HTML没有出现问题,但是你如果想要使用v-for的方式进行渲染,那么初始化就不会起作用。

3、HTML通过data方式引入

<div class="grid" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  ...
</div>

最后效果

img

img

响应式

可以看出来masonry通过少量的配置就可以达到惊人的效果。

至于更多的配置内容,可以参考下面这篇文章

https://blog.csdn.net/a419419/article/details/83858984

有条件的话,也可以直接到masonry官网进行查看

masonry


6.12更新

最近做项目时想要用瀑布流,但是发现一个BUG,当图片数据已经被获取,但是图片未加载完时,可能会出现图片重叠的现象,这种现象经过测试往往出现在刷新浏览器的时候。

img

解决方法

引入第三方库

imagesloadedgithub.com

这个库会判断元素中的图片是否已经加载完成,并且在加载完成后调用回调函数。

所以改一下上面的代码:

import imagesloaded from 'imagesloaded'; // 引入imagesloaded库

updated() {
  let grid = document.querySelector('.grid');
  let msnry = new Masonry(grid, {
    // options...
    itemSelector: '.grid-item',
    columnWidth: 300,
  });

  imagesloaded('.grid-item', () => {
    msnry.layout(); // 图片加载完成后重新绘制。
  });
}

img

可以看到当图片加载完成后会进行重新排版

参考资料

https://segmentfault.com/a/1190000013675077