这么简单的瀑布流,你确定不看

背景

在工作中我们或多或少都遇到过需要用到瀑布流的列表或者需求,那么我们怎么实现瀑布流呢?今天我就给大家带来一个简单的实现方法。给大家做打个样。

技术

  • vue3
  • vite

源码地址

瀑布流地址

后面有时间会将此源码封装成公共组件库-->供大家下载使用--如果大家感兴趣的话可以关注一下

HTML

html 复制代码
<template>
  <div>
    <button @click="addCard">增加</button>
    <div class="card">
      <div class="card-list"
      v-waterfall
      v-for="(item,index) in list" :key="index"
      :style="{backgroundColor:item.color,height:item.height}"
      >
        <p class="text"> {{ index }} </p>
      </div>
    </div>

  </div>
</template>

css

这儿注意-->因为在js中我使用的是transform,所以需要使用到定位

css 复制代码
.card {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  width: 700px;
}
.card-list {
  position: absolute;
  width: 200px;
}

js

实现逻辑:

  • 声明一个列表的高度数组,保存每列的高度,然后获取最小高度的位置,方便定位过去
  • 自定义指令:v-waterfall-->通过mounted拿取到dom元素
  • 获取每列的最小高度就是你当前元素需要的top值,然后根据最小高度的索引值*宽度=left值
  • 最后将其赋值给transform即可--
  • 然后将高度在此(tabulationHeights)基础上叠加即可下次计算

基本逻辑也就完成了。简单吧

javascript 复制代码
import { onMounted, ref, nextTick } from "vue";

const list = ref([
  {color:'#76da6e',height:'100px'},
  {color:'#40a988',height:'70px'},
  {color:'#2384c4',height:'120px'},
  {color:'#106ba3',height:'80px'},
  {color:'#0a589e',height:'110px'},
  {color:'#0a4e98',height:'90px'},
  {color:'#09408c',height:'100px'},
  {color:'#083680',height:'130px'},
]);
const tabulationHeights = ref([0,0,0,0]);

const updateLayout = (el) => {
  const columns = getMinTabulationHeight(tabulationHeights.value);
  const top = tabulationHeights.value[columns];
  const left = columns * el.clientWidth;
  el.style.transform = `translate(${left}px,${top}px)`;
  tabulationHeights.value[columns] += el.offsetHeight;
}

const getMinTabulationHeight = (arr) =>{
  let min = Math.min(...arr);
  return arr.indexOf(min) !== -1 ? arr.indexOf(min) : 0;
}

const vWaterfall = {
  mounted: (el) => {
    updateLayout(el);
  },
  updated: (el) => {
    // updateLayout(el);
  }
}

// 增加
const addCard = () => {
  // 随机生成高度
  const height = Math.floor(Math.random() * 50 + 100);
  // 随机生成颜色
  const color = '#'+Math.floor(Math.random()*16777215).toString(16);
  list.value.push({color,height:height+'px'});
}

疑问

有朋友可能会问:我列表与列表之间肯定不会没有间隔才对啊!那么请问这个有怎么处理呢?

其实这个很简单,比如你是要封装一个组件的话,你只需要传递一个GAP的值:然后拿到这个间距去参与计算即可:如以下代码

javascript 复制代码
const updateLayout = (el) => {
  const columns = getMinTabulationHeight(tabulationHeights.value);
  const top = tabulationHeights.value[columns] + 20;
  const left = (columns * el.clientWidth) + (columns * 20);
  el.style.transform = `translate(${left}px,${top}px)`;
  tabulationHeights.value[columns] += el.offsetHeight + 20;
}

总结

以上只是一个简单的模板,大家可以在此基础上优化优化以便达到自己需要的要求。今天的分享到这里就结束了哦!下次有好的点在来跟大家分享,如果觉得不错可以收藏哈这个源码库,后续会更新插件库

相关推荐
我不吃饼干8 小时前
TypeScript 类型体操练习笔记(二)
前端·typescript
光影少年8 小时前
浏览器渲染原理?
前端·javascript·前端框架
小白探索世界欧耶!~8 小时前
Vue2项目引入sortablejs实现表格行拖曳排序
前端·javascript·vue.js·经验分享·elementui·html·echarts
叫我一声阿雷吧10 小时前
JS实现响应式导航栏(移动端汉堡菜单)|适配多端+无缝交互【附完整源码】
开发语言·javascript·交互
GISer_Jing10 小时前
前端营销(AIGC II)
前端·react.js·aigc
NEXT0610 小时前
深度解析 JWT:从 RFC 原理到 NestJS 实战与架构权衡
前端·typescript·nestjs
程序员林北北11 小时前
【前端进阶之旅】节流与防抖:前端性能优化的“安全带”与“稳定器”
前端·javascript·vue.js·react.js·typescript
寻星探路12 小时前
【前端基础】HTML + CSS + JavaScript 快速入门(三):JS 与 jQuery 实战
java·前端·javascript·css·c++·ai·html
未来之窗软件服务13 小时前
未来之窗昭和仙君(六十九)前端收银台行为异常检测—东方仙盟练气
前端·仙盟创梦ide·东方仙盟·昭和仙君
大叔编程奋斗记13 小时前
两个日期间的相隔年月计算
前端·salesforce