在Vue3中,JS实现横向(等宽不等高)瀑布流布局

1.准备好图片结构

template部分:

<div class="pic_list" v-infinite-scroll="load" :infinite-scroll-immediate="false">
	  <!-- :style是计算后的图片的宽高以及top和left的值 -->
      <div v-for="item in picList" :key="item.picId" class="pic_item" :style="{
        width: item.newWidth + 'px',
        height: item.newHeight + 'px',
        left: item.left + 'px',
        top: item.top + 'px'
      }">
        <el-image v-if="item.img" :src="item.img"  />
      </div>
    </div>

css部分

.pic_list {
    position: relative;
    width: 1200px;
    margin: 0 auto;
    height: 1000px;

    .pic_item {
      position: absolute;
      cursor: pointer;

      .el-image {
        display: block;
        width: 100%;
        height: 100%;

        :deep(.el-image__inner) {
          display: block;
          width: 100%;
          height: 100%;
          object-fit: cover;
          border-radius: 12px;
        }
      }
    }
  }

2.纵向瀑布流函数

在util文件夹中新建一个waterfall.js的瀑布流函数文件,添加如下代码:

// 等宽度瀑布流布局 opt是一个配置对象
export const horizontalWaterfall = (opt) => {
  let el = opt.el;
  let column = opt.column;
  let gap = opt.gap;
  let width = 1200; // 图片容器的宽度
  let newWidth = (width - (column - 1) * gap) / column; // 计算出每个图片固定的宽度
  let heightArr = []; // 图片高度的数组
  let item = null;
  let minIdx = -1; // 图片最小高度的索引
  for (let i = 0; i < el.length; i++) {
    item = el[i];
    item.newWidth = newWidth;
    if (item.picHeight === null) item.picHeight = 200;
    if (item.picWidth === null) item.picWidth = 300;
    if (i < column) {
      item.top = 0;
      // 按照宽度比例缩放后的高度值:item.picHeight / (item.picWidth / newWidth)
      item.newHeight = Math.floor(item.picHeight / (item.picWidth / newWidth));
      item.left = i * (newWidth + gap);
      heightArr[i] = item.newHeight;
    } else {
      item.newHeight = Math.floor(item.picHeight / (item.picWidth / newWidth));
      minIdx = getMinHeightIndex(heightArr);
      item.left = el[minIdx].left;
      item.top = heightArr[minIdx] + gap;
      // 更新当前heightArr中的最低高度 = 之前的最低高度 + 当前的高度 + 间隙
      heightArr[minIdx] = heightArr[minIdx] + item.newHeight + gap;
    }
  }
};

// 获取图片高度最小的索引值
const getMinHeightIndex = (arr) => {
  return arr.indexOf(Math.min(...arr));
};

3.在vue文件中使用该函数

    import { horizontalWaterfall } from '../utils/waterfall';
    // 获取图片数据
    const getPicList = async () => {
      const res = await picIndexPicList(state.pageNum, state.pageSize);
      if (res.code && res.code === 200) {
        state.picList = [...state.picList, ...res.rows];
        state.total = res.total;
        // 调用瀑布流函数,实现瀑布流效果
        horizontalWaterfall({
          el: state.picList, // 要改变的数据
          column: 4, // 把图片分成几列
          gap: 10, // 图片之间的间隙
        });
      }
    };

4.最终效果图

在这里插入图片描述

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员禅心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值