• 瀑布流 - Vue3基于Grid布局简单实现一个瀑布流组件


    瀑布流 - Vue3基于Grid布局简单实现一个瀑布流组件

    前言

    在学习Grid布局之时,我发现其是CSS中的一种强大的布局方案,它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局,在刷某书和某宝首页时,我们发现其展示方式就是一种瀑布流,是一种流行的网站页面布局,视觉表现为参差不齐的多栏布局,随着页面向下滚动,这种布局会不断加载数据块并附加到当前尾部。采用瀑布流布局的方式可以打破常规网站布局排版,给用户眼前一亮的新鲜感,更好的适应移动端。
    因此结合二者,本文将通过grid布局简单实现一个瀑布流组件,该组件已开源上传npm,可以直接安装使用,Git地址在文尾。

    实现原理

    1、使用grid布局将页面分为无数个小网格,每个网格高度为1px。

    .grid-content {
        display: grid;
        grid-auto-rows: minmax(1px, 1px);
        overflow: auto;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、宽度根据需要自定义的列数自动分配。

       'grid-template-columns': `repeat(${props.columns}, 1fr)`,
    
    • 1

    3、根据每个卡片窗口的高度计算每个卡片需要跨越几个网格(因为每个网格设置高为1px,所以高度就是需要跨越的网格数)

    'grid-row-end': `span ${gridItem.value.clientHeight - 1}`
    
    • 1

    4、监听瀑布流滚动事件,通过判断滚动条距离底部的高度,在滚动到底部一定距离时加载更多的数据,以实现无限滚动。

    主要代码实现

    gridContent 组件主要代码,循环展示每个条目,根据自定义的列展示不同的列数量,根据触底数据判断获取最新数据。监听传入的数据进行处理,目前只是做了简单处理,后面将通过虚拟列表的形式,动态处理该数据,以增加性能。

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    grid-item 组件代码,主要通过获取组件高度设置跨越的网格数,通过插槽展示每个卡片。

    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    使用示例

    npm install @fcli/vue-grid-waterfall --save-dev 来安装
    
    在项目中使用
    import VueGridWaterfall from '@fcli/vue-grid-waterfall';
    const app=createApp(App)
    app.use(VueGridWaterfall);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例:

    
    <template>
      <div class="content">
        <vue-grid-waterfall :data-list="dataList" :columns="3" @getMoreData="getMoreData" :loading="isLoading">
          <template #slot-scope="{ slotProps }">
            <div class="item" :style="{ height: slotProps.data.height, background: slotProps.data.color }">{{ slotProps.data.color
            }}div>
          template>
        vue-grid-waterfall>
      div>
    template>
    
    <script setup lang="ts">
    import vueGridWaterfall from './plugin/index.vue';
    import { ref, onMounted } from 'vue'
    component: {
      vueGridWaterfall
    }
    
    const dataList = ref<any>([]);
    //获取随机颜色
    const getRandomColor = () => {
      const getColor: any = (color: any) => {
        return (color += '0123456789abcdef'[Math.floor(Math.random() * 16)]) && (color.length == 6) ? color : getColor(color);
      };
      return '#' + getColor('')
    }
    
    const getMoreData = () => {
      isLoading.value = true;
      getData()
    }
    const isLoading = ref(true);
    
    //获取数据
    const getData = () => {
      for (let i = 0; i < 100; i++) {
        dataList.value.push({ height: 50 + Math.random() * 50 + 'px', color: getRandomColor() })
      }
      setTimeout(()=>{
          isLoading.value = false;
      })
    }
    
    onMounted(() => {
      getData()
    })
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    属性属性名称类型可选值
    dataList瀑布流列表数据Array[]
    columns展示的列数number2
    width瀑布流宽度number0
    height瀑布流高度number0
    bottom滚动到底部触发加载数据的距离number50
    loading是否加在载数据boolean加载数据完数据设为false
    #slot-scope插槽objectslotProps.data

    最后

    本组件为初步实现,后续还会结合虚拟滚动,减少dom渲染,当数据量过大时提升性能,欢迎star关注。

    Git地址:https://gitee.com/fcli/vue-grid-waterfall.git

  • 相关阅读:
    Linux安装MongoDB超详细
    用Python做数据分析之数据处理及数据提取
    Matlab:在不同区域设置之间共享代码和数据
    【WordPress】分页插件WP-PageNavi使用教程
    Qt学习总结之QComboBox
    Jetsonnano B01 笔记6:开启USB摄像头
    打造自己的3D模型AI 自动纹理工具
    基础数据结构之——【顺序表】(上)
    活动选择问题(动态规划和贪心算法)
    vue-puzzle-vcode完成验证码拖拽
  • 原文地址:https://blog.csdn.net/qq_34185872/article/details/133079844