当前位置: 首页 > news >正文

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

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

前言

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

实现原理

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

.grid-content {display: grid;grid-auto-rows: minmax(1px, 1px);overflow: auto;
}

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

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

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

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

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

主要代码实现

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

<template><div class="grid-content" ref="gridContent" :style="gridStyle" @scroll="getMoreData"><grid-item v-for="item in showDataList" :key="item.dataIndex" :data="item"><template #slot-scope="slotProps"><slot name="slot-scope" :slotProps="slotProps"></slot></template></grid-item></div>
</template>
<script lang="ts" setup>
import GridItem from './gridItem.vue';
import { ref, watch } from 'vue';const props = defineProps({dataList: {type: Array,default: []},columns: {type: Number,default: 2},width: {type: Number,default: 300},height: {type: Number,default: 400},bottom:{type: Number,default: 50},loading:{type: Boolean,default: true}})const emit=defineEmits(['getMoreData']);const gridStyle = ref({});
const showDataList = ref<any>([])watch(() => props.dataList, (newValue) => {let tempData: any = [];newValue.forEach((item: any, index) => {tempData.push({ ...item, dataIndex: index })})showDataList.value = tempData;gridStyle.value = {'grid-template-columns': `repeat(${props.columns}, 1fr)`,width:props.width + 'px',height:props.height + 'px'}
}, { immediate: true,deep:true })const isLoading=ref<boolean>(false);
watch(()=>props.loading,(newValue:boolean)=>{isLoading.value=newValue;
})const gridContent=ref<any>(null);
//根据触底数据判断获取最新数据
const getMoreData=()=>{const scrollHeight = gridContent.value.scrollHeight || 0;const clientHeight = gridContent.value.clientHeight || 0;const scrollTop = gridContent.value.scrollTop || 0;if(scrollHeight - clientHeight - scrollTop < props.bottom && !isLoading.value){isLoading.value=true;emit('getMoreData');}
}
</script>

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

<template><div class="grid-item" :style="itemStyle"><div ref="gridItem"><slot name="slot-scope" :data="data"></slot></div></div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
defineProps({data: {type: Object,default: () => { }}
})const gridItem = ref<any>(null);
const itemStyle = ref({})onMounted(() => {itemStyle.value = { 'grid-row-end': `span ${gridItem.value.clientHeight - 1}` }
})</script>
<style scoped> 
.grid-item {grid-row-end: span 100;
}
</style>

使用示例

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

示例:


<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>
属性属性名称类型可选值
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

相关文章:

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

瀑布流 - Vue3基于Grid布局简单实现一个瀑布流组件 前言 在学习Grid布局之时&#xff0c;我发现其是CSS中的一种强大的布局方案&#xff0c;它将网页划分成一个个网格&#xff0c;可以任意组合不同的网格&#xff0c;做出各种各样的布局&#xff0c;在刷某书和某宝首页时&…...

ES6面试题总结

1. 谈谈你对 ES6 的理解,为什么要学习es6? ES6是新一代的JS语言标准&#xff0c;对分JS语言核心内容做了升级优化&#xff0c;规范了JS使用标准&#xff0c;新增了JS原生方法&#xff0c;使得JS使用更加规范&#xff0c;更加优雅&#xff0c;更适合大型应用的开发。学习ES6是成…...

mybatisplus,jdbc 批量插入

1.测试用例 项目中遇到在做导入号码的时候我们会用到批量导入&#xff0c;提高入库的速度。接下来我们以10000条为测试用例。 1.1 批量执行sql语句 当需要成批插入或者更新记录时&#xff0c;可以采用Java的批量更新机制&#xff0c;这一机制允许多条语句一次性提交给数据库…...

如何使用IP归属地查询API来追踪网络活动

引言 在当今数字化世界中&#xff0c;了解网络活动的源头和位置对于网络安全、市场研究和用户体验至关重要。IP归属地查询API是一种强大的工具&#xff0c;可以帮助您追踪网络活动并获取有关IP地址的重要信息。本文将探讨如何使用IP归属地查询API来追踪网络活动&#xff0c;以…...

【SQL】S0 系列博文大纲

系列博文大纲 SQL 学习环境建议系列博文相关书籍系列博文大纲阶段进展 SQL 学习环境建议 对于 SQL 语言的学习&#xff0c;博主本地使用&#xff1a;MySQL DataGrip&#xff1b; MySQL 提供本地数据库服务&#xff1b; DataGrip IDE&#xff0c;承担编程运行测试任务&#xf…...

2023年8月体育用品行业数据分析(京东数据产品)

当前&#xff0c;亚运会临近&#xff0c;这也带动了国民对体育消费的热情&#xff0c;体育产品内销逐渐旺盛&#xff0c;“亚运经济”红利开始显现。鲸参谋数据显示&#xff0c;今年8月份&#xff0c;京东平台上体育用品行业的销量为185万&#xff0c;同比增长2%&#xff1b;销…...

国内高校镜像网站

国内各大高校开源镜像站 排名不分前后 清华大学&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/ 北京大学&#xff1a;https://mirrors.pku.edu.cn/ 北京外国语大学&#xff1a;http://​ https://mirrors.bfsu.edu.cn/ ​ 北京理工大学&#xff1a;https://mirrors.bit.e…...

Linux安装kafka-manager

相关链接https://github.com/yahoo/kafka-manager/releases kafka-manager-2.0.0.2下载地址 百度云链接&#xff1a;https://pan.baidu.com/s/1XinGcwpXU9YBF46qkrKS_A 提取码&#xff1a;tzvg 一、安装部署 1.把kafka-manager-2.0.0.2.zip拷贝到目录 /opt/app/elk 2.解压…...

MYSQL索引——B+树讲解

B-/B树看 MySQL索引结构 B-树 B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树.它类似普通的平衡二叉树&#xff0c;不同的一点是B-树允许每个节点有更多的子节点。下图是 B-树的简化图. B-树有如下特点: 所有键值分布在整颗树中&#xff1b; 任何一…...

VB将十进制整数转换成16进制以内的任意进制数

VB将十进制整数转换成16进制以内的任意进制数 数值转换&#xff0c;能够将十进制整数转换成16进制以内的任意进制数 Private Function DecToN(ByVal x%, ByVal n%) As StringDim p() As String, y$, r%p Split("0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F", ",")I…...

基于SpringBoot+Vue的宠物领养饲养交流管理平台设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…...

【图像去噪】【TGV 正则器的快速计算方法】通过FFT的总(广义)变化进行图像去噪(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

windbg调试句柄问题

这里写自定义目录标题 winform&#xff0c;句柄资源不够强&#xff0c;程序crash句柄主程序c程序&#xff0c;加载的插件是c# dll&#xff0c;这时候如何用windbg调试dll库如果查看句柄和对象的关系!handle 怎么能知道哪个句柄是Form对话框的句柄如何查看句柄对应的类对象 winf…...

9月13-14日上课内容 第三章 ELK日志分析系统及部署实例

本章结构 ELK日志分析系统简介 ELK日志分析系统分为 Elasticsearch Logstash Kibana 日志处理步骤 1.将日志进行集中化管理 2.将日志格式化(Logstash) 并输出到Elasticsearch 3.对格式化后的数据进行索引和存储 (Elasticsearch) 4.前端数据的展示(Kibana) Elasticsearch介…...

服务器端应用的安装

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…...

关于硬盘质量大数据分析的思考

近日&#xff0c;看到Backblaze分享了一遍关于硬盘运行监控数据架构的文章&#xff0c;觉得挺有意义的&#xff0c;本文就针对这方面跟大家聊聊。 作为一家在2021年在美国纳斯达克上市的云端备份公司&#xff0c;Backblaze一直保持着对外定期发布HDD和SSD的故障率稳定性质量报告…...

RK3568核心板分区空间不足,如何修改分区大小?

在对评估板进行开发验证时&#xff0c;时常会遇到根目录空间不足的情况&#xff0c;而在其他分区又有冗余空间&#xff0c;这时则需要对分区大小重新进行分配&#xff0c;合理化利用分区空间。 本文将基于HD-RK3568-IOT评估板主要讲解如何修改eMMC分区大小。 ​ 1. 分区表介绍…...

Linux系统怎么修改主机名

【微|信|公|众|号&#xff1a;厦门微思网络】 1.备份主机名文件 首先redhat修改主机名&#xff0c;在进行任何修改之前&#xff0c;请务必备份主机名文件。这样&#xff0c;即使出现意外情况&#xff0c;你也能够轻松恢复到原始状态。使用以下命令备份主机名文件&#xff1…...

BroadcastChannel方法跨浏览器窗口通信

1. 描述 同源 的不同浏览器窗口&#xff0c;Tab 页&#xff0c;frame 或者 iframe 下的不同文档之间可以通过 BroadcastChannel 相互通信。 2. 构造函数 通过 BroadcastChannel 类传入的参数创建实例&#xff0c;传入的参数将指定通道名称&#xff0c;在同源环境下该通道可以…...

山石网科国产化防火墙,打造全方位边界安全解决方案

互联网的快速发展促进了各行各业的信息化建设&#xff0c;但也随之带来了诸多网络安全风险。大部分组织机构采用统一互联网接入方案&#xff0c;互联网出口承担着内部用户访问互联网的统一出口和对外信息服务的入口&#xff0c;因此在该区域部署相匹配的安全防护手段必不可少。…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...