使用Gird布局实现瀑布流效果

之前在插件里做了一个收藏夹和生词本的需求,大概长下面这样,里面的数据是按照瀑布流去做展示的

一、纯css也很好用

瀑布流布局一般的解决方案都是使用js去做动态计算内容高度,然后把内容分配给最短的'管道',实现调补的效果,但是纯js计算起来太费事了

在我逛了一圈百度后,发现css的gird布局完全可以实现瀑布流效果,可以减少很多计算

二、强大的gird

因为之前也没怎么使用grid,都是现查的,详细的可以看看这篇文章

gird是二维的布局,支持同时设置两个方向的数据,包括内容占比、间距等等,这样就很好办事了。我们可以直接设置'管道'的数量,内容动态去设置格子占比即可

话不多说,先封装容器组件 <WaterFall />

1.模板和参数

模板上,我们只要弄好容器就好了,里面展示什么内容不需要关心,直接用slot就好了

参数不需要支持太多,配置下面的就够了

  • col:管道的数量
  • colGap:管道的列间距
  • girdRowHeight:每一个网格的高度
  • rowGap:内容间行间距
vue 复制代码
<template>
  <div class="waterfall-wrapper" ref="waterfallRef" :style="wrapperStyle">
    <slot></slot>
  </div>
</template>

<script setup lang="ts">
const props = defineProps({
    col: {
      type: Number,
      default: 3
    },
    colGap: {
      type: Number,
      default: 20
    },
    girdRowHeight: {
      type: Number,
      default: 5
    },
    rowGap: {
      type: Number,
      default: 20
    }
})
</script>

<style leng="scss" scoped>
.waterfall-list-wrapper {
  display: grid;
  align-items: start;
}
</style>
4.容器的配置style
vue 复制代码
const wrapperStyle = computed(() => {
    return {
        // 需要多少列,每一列均分空间
        'grid-template-columns': `repeat(${props.col}, 1fr)`,
        
        // 隐式网格的高度
        'grid-auto-rows': `${props.girdRowHeight}px`
    }
})
4.动态计算内容占比
vue 复制代码
const waterfallRef = ref(null)
const updateList = () => {
    const els = Array.from(waterfallRef.value.children)
    els.forEach((el: any) => {
        // 内容占用的网格数
        const contentRows = Math.ceil(el.clientHeight / props.girdRowHeight)
        // 间距占用的网格数
        const gapRows = Math.ceil(props.rowGap / props.girdRowHeight)
    
        const rows = contentRows + gapRows
        
        // 上边框自适应
        el.style.girdRowStart = 'auto'
        
        // 设置下边框为跨度 rows 个网格的大小
        el.style.girdRowEnd = `span ${rows}`
    })
}

执行updateList,就可以实现瀑布流布局,如果有改变内容高度的操作,在操作完成后,再执行一遍updateList即可

三、总结一下

使用gird布局去实现瀑布流的重点在于,预设好隐式网格的高度,计算出内容占用的网格数,再给gird的元素设置上gird-row即可

相关推荐
小poop13 小时前
CSS 基础与实战:从入门到精通网页美化
前端
Csvn14 小时前
运行时性能
前端
Never_every9915 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck15 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
空中湖16 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
狮子座的男孩17 小时前
html+css基础:25、3D变换(3D空间与景深/透视点的位置/位移/旋转/缩放/多重变换/背部可见性)
css·经验分享·html·旋转·透视点·缩放/位移·3d变换/空间与景深
欣欣之王来了18 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒18 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师18 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端
特立独行的猫A18 小时前
10 MB 的桌面 AI 客户端:用仓颉 + 系统 WebView 替代 Electron
前端·harmonyos