• 如何用Vue3实现瀑布流效果
  • 发布于 2个月前
  • 624 热度
    0 评论
  • 封锁爱
  • 0 粉丝 47 篇博客
  •   
前言

在Vue3的浪潮中,瀑布流布局以其高效利用空间、动态加载的优势成为焦点。本文将深入探索Vue3如何实现瀑布流,从基础到实践,分享实战技巧与心得,助力你轻松驾驭这一热门布局方式。瀑布流布局,犹如自然瀑布般流畅,通过错落有致、高度不一的图片排列,创造出一种独特的视觉美感,不仅令人赏心悦目,更极大地提升了用户的浏览体验。


实现
我这里主要用纯js实现。也可以用别的方式实现瀑布流每种方式遇到的难点不同
效果展示

在窗口宽度发生变化时,瀑布流重新排列,给用户带来了良好的体验
代码分析
html
html部分非常简单就一个盒子
<template>
  <div class="container" id="contatiner" ref="divContatiner"></div>
</template>
css
给盒子设置一个边框,这里的宽度给上百分比这样就能根据窗口的变化而变化
.container {
  width: 50%;
  margin: 0 auto;
  border: 2px solid;
  position: relative;
}
js
js部分是最重要的,这里先说一下实现的思路。
我给图片一个相同的宽度,var imgWidth = 220;
拿到父容器var divContatiner = document.getElementById("contatiner");。
-这样可以计算出当前页面可以放得下多少列,并计算出图片之间间隙的值
img.onload = setPoisions;这一句是在图片加载完成后再给他计算出图片的位置,这样不会导致所有图片的坐标都是0
// 堆代码 duidaima.com
//这块代码主要用来创建放图片的标签
function createImgs() {
  for (var i = 0; i <= 16; i++) {
    const src = "images/" + i + ".jpg";
    const img = document.createElement("img"); //创建img标签
    img.onload = setPoisions;
    img.src = src; //设置src路劲
    img.className = "box"; // 添加box类
    img.style.position = "absolute"; // 设置position
    img.style.transition = "0.3s"; // 设置transition
    divContatiner.appendChild(img); //将创建的img添加到容器中
    img.width = imgWidth;
  }
}
// 计算出一共多少列,以及每一列之间的间隙
function cal() {
  const containerWidth = divContatiner.clientWidth; //获取父容器的宽度
  // 计算列的数量
  const clolumns = Math.floor(containerWidth / imgWidth);

  //计算间隙
  const spaceNumber = clolumns + 1; //间隙数量
  const leftSpace = containerWidth - clolumns * imgWidth; //计算剩余的空间
  const space = leftSpace / spaceNumber; //每个间隙的值
  return {
    space: space,//间隙值
    clolumns: clolumns,//列的数量
  };
}
接下来重点思路,现在可以拿到列数跟间隙值。我们先创建一个数组主要用来存放每一列的纵坐标。每次图片都插入到最小的纵坐标当中。有了这些值我们可以计算出每张图片的横坐标与纵坐标。

这样图片就会依次插入
function setPoisions() {
  var info = cal(); //得到列数间隙空间
  var nextTops = new Array(info.clolumns); //该数组长度为列数,每一项表示该列的下一个图片的纵坐标
  nextTops.fill(0);
  for (var i = 0; i < divContatiner.children.length; i++) {
    var img = divContatiner.children[i];
    //找到nextTops中的最小值作为当前图片的纵坐标
    const minTop = Math.min.apply(null, nextTops);
    img.style.top = minTop + "px";
    //重新设置数组这一项的下一个top值
    const index = nextTops.indexOf(minTop);
    nextTops[index] += img.height + info.space; //使得使用的第几列的top改变
    // 横坐标
    const left = (index + 1) * info.space + index * imgWidth;
    img.style.left = left + "px";
  }
  const max = Math.max.apply(null, nextTops); //求纵坐标的最大值
  divContatiner.style.height = max + "px"; //设置成整个容易的高度
}
var nextTops = new Array(info.clolumns);这个数组用来存放每一列的中坐标,长度为多少列。nextTops.fill(0);一开始所有的中坐标都是0
const minTop = Math.min.apply(null, nextTops);找到最小的中坐标img.style.top = minTop + "px";这样就可以算出这一张图片的纵坐标
const index = nextTops.indexOf(minTop);nextTops[index] += img.height + info.space;重置这一项的纵坐标,使这一列的纵坐标发生改变
const left = (index + 1) * info.space + index * imgWidth;横坐标的值就是间隙加上图片的宽度 img.style.left = left + "px";
const max = Math.max.apply(null, nextTops); divContatiner.style.height = max + "px"; 重置盒子的高度
var timerId = null;
window.onresize = function () {
  if (timerId) {
    clearTimeout(timerId);
  }
  timerId = setTimeout(setPoisions, 300);
};
这一段代码是做了一个防抖,这样在变化的后0.3秒才会重新瀑布流布局。
用户评论