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

React 图片瀑布流

 思路:

根据浏览器宽度,确定列数,请求的图片列表数据是列数的10倍,按列数取数据渲染

Index.js:

import React from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { SinglePageHeader } from '../../../../../components/light'
import InfiniteScroll from 'react-infinite-scroll-component'
import { Divider, Skeleton } from 'antd'
import useList from './useList'
import LazyLoad from 'react-lazy-load'import './index.css'function Index(props) {const {dataSource,isHasMore,columnCount,handleSearch,handleImgDrawSameStyleClick,} = useList(props)return (<div className="m-ai-img-wrap-box"><div className={`m-ai-img-wrap-chat`}><SinglePageHeader title="AI绘画作品展示"></SinglePageHeader><div className="m-ai-img-list" id="scrollableDiv"><InfiniteScrolldataLength={dataSource.length}next={handleSearch}refreshFunction={() => handleSearch({ page: 1, isRefresh: true })}pullDownToRefreshpullDownToRefreshThreshold={50}pullDownToRefreshContent={<h3 style={{ textAlign: 'center' }}>&#8595; 下拉刷新</h3>}releaseToRefreshContent={<h3 style={{ textAlign: 'center' }}>&#8593; 释放刷新</h3>}hasMore={isHasMore}loader={<Skeletonavatarparagraph={{rows: 3,}}activeclassName="m-h5-lesson-play-skeleton"/>}endMessage={dataSource.length === 0 ? null : (<Divider plain>已经到底啦~</Divider>)}scrollableTarget="scrollableDiv"><div className="m-ai-img-list-inner">{Array.from({ length: columnCount }, () => '').map((item, index) => (<div className="m-ai-img-list-column" key={index}>{dataSource.filter((item, dataSourceIndex) =>dataSourceIndex % columnCount === index).map((item) => (<div key={item.imgUid}><LazyLoad className="m-ai-img-lazy-load"><imgsrc={item.imgUrlCdn}className="m-ai-img"alt="图片"onClick={() => handleImgDrawSameStyleClick(item)}></img></LazyLoad></div>))}</div>))}</div>{dataSource.length === 0 ? (<Skeletonavatarparagraph={{rows: 3,}}activeclassName="m-h5-lesson-play-skeleton"/>) : null}</InfiniteScroll></div></div></div>)
}const mapStateToProps = (state) => {return {collapsed: state.getIn(['light', 'collapsed']),isRNGotToken: state.getIn(['light', 'isRNGotToken']),}
}const mapDispatchToProps = (dispatch) => {return {onSetState(key, value) {dispatch({ type: 'SET_LIGHT_STATE', key, value })},onDispatch(action) {dispatch(action)},}
}export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Index))

useList.js:

import { useState, useEffect } from 'react'
import { Form } from 'antd'
import Api from '../../../../../api'
import { message } from 'antd'
import * as clipboard from 'clipboard-polyfill/text'export default function useList(props) {const [total, setTotal] = useState(10)const [current, setCurrent] = useState(1)let tempCount = Math.floor((window.innerWidth - 10) / 180)tempCount = Math.floor((window.innerWidth - (5 + tempCount * 5)) / 180)console.log('tempCount1', tempCount)//把dataSource和pageSize单独放在一起是为了避免切换pageSize时的bugconst [state, setState] = useState({dataSource: [],pageSize: tempCount * 10,})const [isHasMore, setIsHasMore] = useState(true)// eslint-disable-next-lineconst [username, setUsername] = useState(localStorage.getItem('username'))const [form] = Form.useForm()// eslint-disable-next-lineconst [initValues, setInitValues] = useState({})// eslint-disable-next-lineconst [columnCount, setColumnCount] = useState(tempCount)//搜索const handleSearch = ({page = current,pageSize = state.pageSize,isRefresh = false,} = {}) => {if (isRefresh) {setState({dataSource: [],pageSize: tempCount * 10,})}let searchData = { pageNum: page, pageSize }Api.h5.sdImgSearch(searchData).then((res) => {if (res.code === 200) {const { pageNum, pageSize, total } = res.datalet list = res.data.listif (isRefresh) {setState({dataSource: [...list],pageSize: res.data.pageSize,})} else {setState({dataSource: [...state.dataSource, ...list],pageSize: res.data.pageSize,})}setTotal(res.data.total)const currentTemp = res.data.pageNum + 1setCurrent(currentTemp)setIsHasMore(pageNum < Math.ceil(total / pageSize))}})}//添加或编辑const handleFinish = (values) => {console.log('Success:', values)Api.h5.exchangeCodeAppUse(values).then((res) => {if (res.code === 200) {message.success('恭喜您,兑换成功')//props.history.push('/h5/index/me')}})}//校验失败const handleFinishFailed = (errorInfo) => {console.log('Failed:', errorInfo)}//退出const handleQuit = () => {Api.light.userLogout().then((res) => {if (res.code === 200) {props.history.push('/h5/login')window.localStorage.removeItem('username')window.localStorage.removeItem('token')}})}//跳转const handleJumpPage = (path) => {// eslint-disable-next-lineprops.history.push(path)}const handleCopy = (text) => {clipboard.writeText(text).then(() => {message.success('复制成功')})}const handleImgDrawSameStyleClick = (item) => {console.log(item)props.history.push(`/single/home/sdSimple?modelId=${item.id}&name=${item.name}&link=${item.link}&imgUid=${item.imgUid}`)}useEffect(() => {if (window.platform === 'rn') {if (props.isRNGotToken === true) {handleSearch()}} else {handleSearch()}// eslint-disable-next-line}, [props.isRNGotToken])return {username,form,initValues,dataSource: state.dataSource,total,current,pageSize: state.pageSize,isHasMore,columnCount,handleFinish,handleFinishFailed,handleQuit,handleJumpPage,handleCopy,handleSearch,handleImgDrawSameStyleClick,}
}

index.css:

.m-ai-img-wrap-box{display: flex;justify-content: center;background: #ddd;background: #ddd;position: absolute;top: 0;left: 0;right: 0;bottom: 0;overflow: hidden;}
.m-ai-img-wrap-chat{position: relative; display: flex;flex-direction: column;width: 100%;background: #ededed;}
.m-ai-img-main{flex:1;display: flex;flex-direction: column;overflow-y: auto;}
.m-ai-img-list{flex: 1;padding: 0px 0;overflow-y: auto;}
.m-ai-img-list-inner{position: relative;padding: 0 0 0 5px; display: flex; flex-wrap: wrap;justify-content: center;}
.m-ai-img-list-column{display: flex;flex-direction: column;width: 175px;margin: 0 5px 0 0;}
.m-ai-img-lazy-load{position: relative;min-width: 175px; display: flex;flex-direction: column;justify-content: center; min-height: 175px;margin: 0 0 5px 0;border-radius: 5px; background: #dddddd;}
.m-ai-img{width: 175px;border-radius: 5px;}

效果图:

参考链接:

https://chat.xutongbao.top/

相关文章:

React 图片瀑布流

思路&#xff1a; 根据浏览器宽度&#xff0c;确定列数&#xff0c;请求的图片列表数据是列数的10倍&#xff0c;按列数取数据渲染 Index.js: import React from react import { connect } from react-redux import { withRouter } from react-router-dom import { SinglePag…...

C++数据结构X篇_21_插入排序(稳定的排序)

文章目录 1. 插入排序原理2. 算法图解3. 核心代码&#xff1a;4. 插入排序整体代码实现 1. 插入排序原理 插入排序是一种最简单直观的排序算法&#xff0c;它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相…...

【Unity】3D跑酷游戏

展示 finish_all * 方块跑酷 1.教程链接 翻墙&#xff1a;https://www.youtube.com/watch?v9ZEu_I-ido4&listPLPV2KyIb3jR53Jce9hP7G5xC4O9AgnOuL&index3 2.基础制作 最终成果 2.1 基本场景 1.创建Cube作为跑道 1&#xff09;记得把位置Reset&#xff1b; 2&#…...

bp前端验证码绕过及token绕过

前端验证码绕过及token绕过 原文参考&#xff1a;xiu 文章目录 前端验证码绕过及token绕过原文参考&#xff1a;[xiu](http://www.xiusafe.com/2023/10/25/%E9%AA%8C%E8%AF%81%E7%A0%81%E7%BB%95%E8%BF%87/)1 验证码爆破1. 登录Pikachu&#xff0c;先获取登录的api接口2 验证码…...

Jmeter(十四):跨线程组传递jmeter变量及cookie的处理详解

setUp线程组 setUp thread group 一种特殊类型的线程组&#xff0c;用于在执行常规线程组之前执行一些必要的操作。 在 setup线程组下提到的线程行为与普通线程组完全相同。不同的是执行顺序--- 它会在普通线程组执行之前被触发&#xff1b; 应用场景举例&#xff1a; A、测…...

css实现圆形进度条

能用现成组件就用&#xff0c;实现不行再自己写&#xff0c;因为牵扯到上传文件&#xff0c;进度实时出不来&#xff0c;所以只能使用dom元素操作&#xff1b; 1.实现 效果&#xff1a; 上图是100%&#xff0c;如果需要根据百分比显示&#xff0c;我们需要看下代码里面left和…...

适用于 Windows 10 和 Windows 11 设备的笔记本电脑管理软件

便携式计算机管理软件使 IT 管理员能够简化企业中使用的便携式计算机的部署和管理&#xff0c;当今大多数员工使用Windows 笔记本电脑作为他们的主要工作机器&#xff0c;他们确实已成为几乎每个组织不可或缺的一部分。由于与台式机相比&#xff0c;笔记本电脑足够便携&#xf…...

YOLOv5论文作图教程(1)— 软件介绍及下载安装(包括软件包+下载安装详细步骤)

前言:Hello大家好,我是小哥谈。在学习YOLOv5算法的过程中,很多同学都有发表论文的需求。作为文章内容的支撑,图表是最直接的整合数据的工具,能够更清晰地反映出研究对象的结果、流程或趋势。在发表论文的时候,审稿人除了关注论文的内容和排版外,也会审核图表是否清晰美观…...

AutoCAD 2024 Mac中文附激活补丁 兼容M1.M2电脑

AutoCAD 2024是一款功能强大的CAD设计绘图工具&#xff0c;旨在帮助用户创建和编辑高质量的设计图纸和模型。该软件支持2D和3D设计&#xff0c;具有丰富的功能和工具&#xff0c;可用于绘图、建模、注释、标注、尺寸设置等多种操作。AutoCAD 2024还引入了智能对象捕捉、实时预览…...

Jmeter基础---while控制器举例说明

一、 While 控制器 首先创建一个While Controller (While 循环控制器) ​​ 设置界面如下&#xff1a; Condition (function or variable) &#xff1a;条件说明 条件为 Flase 的时候&#xff0c;才会跳出 While 循环&#xff0c;否则一直执行 While 控制器下的样例 1、不填…...

正点原子嵌入式linux驱动开发——RGB转HDMI

目前大多数的显示器都提供了HDMI接口&#xff0c;HDMI的应用范围也越来越广&#xff0c;但是STM32MP157这颗芯片原生并不支持HDMI显示。可以通过RGB转HDMI芯片将RGB信号转为HDMI信号&#xff0c;这样就可以连接HDMI显示器了。本章就来学习一下如何在正点原子的STM32MP1开发板上…...

前端时间分片渲染

在经典的面试题中&#xff1a;”如果后端返回了十万条数据要你插入到页面中&#xff0c;你会怎么处理&#xff1f;” 除了像 useVirtualList 这样的虚拟列表来处理外&#xff0c;我们还可以通过 时间分片 来处理 通过 setTimeout 直接上一个例子&#xff1a; <!--* Autho…...

亿图导出word和PDF中清晰度保留方法

步骤一 在亿图软件中画一个元件大小搭配合理的图。注意字体大小的安排&#xff0c;尤其是角标的大小要合适&#xff0c;示范如下 选中所有元器件&#xff0c;右键使用组合功能将电路图组合为一个整体 步骤二&#xff1a; 将亿图软件中的图保存为SVG格式。示范如下 在导出到…...

chatGPT结构及商业级相似模型应用调研

GPT前言 说明 ChatGPT这项技术的历史可以追溯到2018年&#xff0c;当时由Facebook实验室的团队开发出该技术&#xff0c;以开发聊天机器人为目的。随后&#xff0c;ChatGPT在2019年由来自谷歌的DeepMind团队在国际会议ICLR上发表了论文&#xff0c;其中提出了ChatGPT的技术框架…...

HarmonyOS鸿蒙原生应用开发设计- 华为分享图标

HarmonyOS设计文档中&#xff0c;为大家提供了独特的华为分享图标&#xff0c;开发者可以根据需要直接引用。 开发者直接使用官方提供的华为分享图标内容&#xff0c;既可以符合HarmonyOS原生应用的开发上架运营规范&#xff0c;又可以防止使用别人的内容产生的侵权意外情况等&…...

Java基础-反射

代理相关 为什么需要代理&#xff1f; 代理可以无侵入式的对方法进行增强&#xff0c;而不需要修改原始方法的代码&#xff0c;这样就可以在不修改原始方法的情况下&#xff0c;对方法进行增强。 代理长什么样子&#xff1f; 代理里面就是对象要被代理的方法 Java通过什么方式…...

计算机毕设 大数据二手房数据爬取与分析可视化 -python 数据分析 可视化

# 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…...

【转载】 Bytedance火山引擎智能拥塞控制算法 VICC

BytedanceTechBlog : 火山引擎实时、低延时拥塞控制算法的优化实践 火山引擎 网站如何利用播放器节省20%点播成本点击下面的链接进入原文:原创 翟强俊、唐辉 字节跳动技术团队 2023-10-18 11:59 发表于北京 一些专利摘要 火山引擎智能拥塞控制算法 VICC(Volcano Intelligent…...

Postman如何测试WebService接口

前言: 由于工作所需,需要使用Postman测试工具,对基于ws规范的WebService接口进行测试.在经过多种尝试后,终于找到了正确的测试方法.下面我便详细记录测试步骤,以便以后再次测试时可以拿来主义. 第一步:确保WebService服务端正常启动(注意服务端各个接口发布的url地址) 第二步…...

微服务-Eureka

文章目录 提供者与消费者Eureka注册中心搭建EurekaServer服务注册服务发现项目结构 提供者与消费者 Eureka注册中心 服务消费者该如何获取服务提供者的地址信息&#xff1f; 服务提供者启动时向eureka注册自己的信息 eureka保存这些信息 消费者根据服务名称向eureka拉取提供者信…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...