Ant Design Card 组件展示图片

news2025/3/11 3:23:54

文章目录

  • Ant Design Card 组件展示图片
    • 理解card组件结构
      • 隐藏卡片内容区域
    • 下拉时加载图片卡片
      • 加载更多
      • 代码
    • 分页的方式加载图片列表【推荐】
      • 实现思路
      • 代码demo
      • 缩略图
      • 在card组件下发显示图片文件名
      • 卡片操作
    • 分页

Ant Design Card 组件展示图片

官方文档:
Card卡片组件 https://4x.ant.design/components/card-cn/#Card
ProCard高级卡片 https://procomponents.ant.design/components/card

Card卡片
通用卡片容器。

何时使用#
最基础的卡片容器,可承载文字、列表、图片、段落,常用于后台概览页面。

理解card组件结构

在这里插入图片描述如上图,Card组件分成如上组成部分,

  1. header这部分 是,title属性来配置
  2. 卡片封面 是sove属性来配置
  3. 卡片内容区域 Card.Meta 来配置
  4. 卡片动作部分,是action属性来配置

隐藏卡片内容区域

我们使用一个名为 custom-card 的类名来设置卡片容器的样式,并通过 bodyStyle 属性将内容区域的样式设置为 display: none,完全隐藏内容区域。

在这里插入图片描述

下拉时加载图片卡片

需求是展示支持分页的图片,并且希望在下拉时加载新的图片卡片,可以使用 Ant Design 的 List 组件和滚动事件来实现。

容器的高度自适应,并且卡片在宽度不足时自动换行显示,可以使用 CSS 中的 Flexbox 布局来实现

  return (
    <div style={{ display: 'flex', flexWrap: 'wrap' }} onScroll={handleScroll}>
      <List
        grid={{ gutter: 16, column: 4 }}
        dataSource={data}
        loading={loading}
        loadMore={loading ? <Spin /> : undefined}
        renderItem={(item) => (
          <List.Item style={{ flexBasis: '25%' }}>
            <Card cover={<img alt="Example Image" src={item} />} />
          </List.Item>
        )}
      />
    </div>
  );

我们将容器的样式设置为 display: ‘flex’,并使用 flexWrap: ‘wrap’ 让卡片在宽度不足时自动换行显示。

将卡片项的样式设置为 flexBasis: ‘20%’,这样每个卡片项将占据容器宽度的 20%。通过将 column 属性设置为 5,我们让 List 组件一行显示 5 个卡片。

加载更多

将List组件的 loadMore 属性的值设置为一个函数,用于触发加载更多数据的操作。

在这里插入图片描述
将 handleLoadMore 定义为一个函数,用于触发加载更多数据的操作。如果正在加载中,将 handleLoadMore 设置为空函数;否则,将其设置为 fetchData 函数,以触发加载更多数据。

通过这个修改,当滚动到底部时,将触发加载更多数据的操作,并通过模拟异步加载数据的方式展示加载更多的效果。

代码

import { List, Card, Spin } from 'antd';
import { useEffect, useState } from 'react';

const ImageList: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<string[]>([]);

  const fetchData = () => {
    setLoading(true);

    // 模拟异步加载数据
    setTimeout(() => {
      const newData = Array.from({ length: 10 }, (_, index) => `https://via.placeholder.com/300?text=Image${index + 1}`);
      setData((prevData) => [...prevData, ...newData]);
      setLoading(false);
    }, 1000);
  };

  useEffect(() => {
    fetchData();
  }, []);

  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
    const isAtBottom = scrollTop + clientHeight === scrollHeight;

    if (isAtBottom && !loading) {
      fetchData();
    }
  };

  const handleLoadMore = loading ? () => {} : null;

  return (
    <div style={{ display: 'flex', flexWrap: 'wrap' }} onScroll={handleScroll}>
      <List
        grid={{ gutter: 16, column: 5 }}
        dataSource={data}
        loading={loading}
        loadMore={handleLoadMore}
        renderItem={(item) => (
          <List.Item style={{ flexBasis: '20%' }}>
            <Card cover={<img alt="Example Image" src={item} />} />
          </List.Item>
        )}
        
      />
    </div>
  );
};

export default ImageList;

分页的方式加载图片列表【推荐】

使用分页的方式可以更加可控地展示数据,并提供更好的用户体验。通过显示当前页数、总页数以及提供页码切换的功能,用户可以清楚地知道当前所处的页面位置,并且可以自由地在不同页面之间进行切换。

实现思路

我更喜欢使用分页而不是加载更多的方式来展示数据,您可以结合 Ant Design 的 Pagination 组件来实现分页效果

代码demo

import { List, Card, Pagination } from 'antd';
import { useEffect, useState } from 'react';

const ImageList: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<string[]>([]);
  const [page, setPage] = useState(1);
  const pageSize = 12; // 每页显示的图片数量

  const fetchData = () => {
    setLoading(true);

    // 模拟异步加载数据
    setTimeout(() => {
      const newData = Array.from({ length: pageSize }, (_, index) => `https://via.placeholder.com/300?text=Image${(page - 1) * pageSize + index + 1}`);
      setData(newData);
      setLoading(false);
    }, 1000);
  };

  useEffect(() => {
    fetchData();
  }, [page]);

  const handlePageChange = (pageNumber: number) => {
    setPage(pageNumber);
  };

  return (
    <div>
      <List
        grid={{ gutter: 16, column: 4 }}
        dataSource={data}
        loading={loading}
        renderItem={(item) => (
          <List.Item>
            <Card cover={<img alt="Example Image" src={item} />} />
          </List.Item>
        )}
      />
      <Pagination current={page} pageSize={pageSize} total={100} onChange={handlePageChange} />
    </div>
  );
};

export default ImageList;

缩略图

import { List, Card, Pagination } from 'antd';
import axios from 'axios';
import { useEffect, useState } from 'react';

const ImageList: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<string[]>([]);
  const [page, setPage] = useState(1);
  const pageSize = 12; // 每页显示的图片数量

  const fetchData = async () => {
    setLoading(true);

    try {
      let token = localStorage.getItem('token');
      if (null === token) {
          token = '';
      }

      const response = await axios.get('/api/v1/imageManage/listThumbImages', {
        params: {
          page: page,
          pageSize: pageSize,
        },
        headers: {
          Authorization: `Bearer ${token}`,  // 替换为您的 Bearer Token
        },
      });

      console.log("listThumbImages  response data: ", response.data)
		  //前端只通过 Base64 字符串无法确定图片的格式。Base64 只是一种表示图像数据的编码方式,并不能直接指示图像的格式。
		  //在前端展示 Base64 图片时,通常需要提供图像的 MIME 类型来指示图像的格式。MIME 类型是一种标识数据类型的字符串,例如 "image/jpeg" 表示 JPEG 图像,"image/png" 表示 PNG 图像。
		  // 将图像的 MIME 类型一并返回,这样前端就能够根据提供的 MIME 类型来正确解析和显示图像

      //根据文件名组装图像的 MIME 类型
      const updatedData = response.data.map(item => {
        const fileExtension = item.FileName.split('.').pop().toLowerCase();
        let imageFormat = "image/jpeg"; // 默认格式为 JPEG
        if (fileExtension === "png") {
          imageFormat = "image/png";
        } else if (fileExtension === "gif") {
          imageFormat = "image/gif";
        }
  
        return {
          ...item,
          ImageFormat: imageFormat,
        };
      });


      setData(updatedData);
      setLoading(false);
    } catch (error) {
      console.error('Error fetching thumbnails:', error);
      setLoading(false);
    }
  };


  useEffect(() => {
    fetchData();
  }, [page]);


  const handlePageChange = (pageNumber: number) => {
    setPage(pageNumber);
  };

  return (
    <div>
      <List
        grid={{ gutter: 16, column: 6 }}
        dataSource={data}
        loading={loading}
        renderItem={(item: any) => (
          <List.Item>
            <Card
              cover={
                item.ThumbnailBase64 ? (
                  <img alt="Example Image" src={`data:${item.ImageFormat};base64,${item.ThumbnailBase64}`} />
                ) : (
                  <div>No Thumbnail</div>
                )
              }
            />
          </List.Item>
        )}
      />
      <Pagination current={page} pageSize={pageSize} total={100} onChange={handlePageChange} />
    </div>
  );
};

export default ImageList;

代码细节解释:

  1. 每行显示多个?
<List
    grid={{ gutter: 16, column: 6 }}  

grid 属性设置为 { gutter: 16, column: 6 },表示创建一个具有 6 列的网格布局,并且网格项之间的间距为 16 像素。

在 List 组件中,grid 属性用于定义网格布局的样式。它接受一个对象作为参数,该对象包含两个属性:gutter 和 column。

  • gutter:用于设置网格项之间的间距。可以将其设置为一个数字来表示像素值,或者设置为一个数组 [水平间距, 垂直间距] 来分别表示水平和垂直方向上的间距。
  • column:用于设置网格的列数。可以将其设置为一个数字来表示列数,或者设置为一个数组 [列数, 列宽] 来分别表示列数和列宽。
  1. 分页?
    如下,添加 分页组件Pagination即可
    在这里插入图片描述
    为 Card 添加预览、下载和删除功能的按钮

通过以上修改,预览、下载和删除的图标会在鼠标悬停在 Card 上时放大并显示。
在上述 CSS 文件中,我们通过设置 .image-actions 类的样式来实现鼠标悬停时的显示效果,并使用 .custom-card:hover .image-actions 选择器来控制悬停时图标的显示。我们还设置了 .icon 类的样式,用于调整图标的大小和颜色。

实现鼠标悬停时图标变色的效果,你可以使用 CSS 的 :hover 伪类选择器来设置图标的样式

  .icon-wrapper {
    display: flex;
    gap: 10px;
  }
  
  .icon-wrapper .icon {
    font-size: 24px;
    color: #000;
    cursor: pointer;
  }
  
  .icon-wrapper .icon:hover {
    color: #ff0000; /* 设置图标的悬停颜色 */
  }

在card组件下发显示图片文件名

Meta官方说明:https://4x.ant.design/components/card-cn/#Card.Meta

要将文件名显示在卡片的底部,您可以在 Card 组件中添加一个位于底部的 Meta 组件,并将文件名作为 Meta 组件的 description 属性。

在这里插入图片描述
可以利用 Card.Meta 支持更灵活的内容

卡片操作

官方文档:https://4x.ant.design/components/card-cn/#Card
使用 actions 卡片操作组,位置在卡片底部

在这里插入图片描述

分页

分页组件用法:

<Pagination current={page} pageSize={pageSize} total={totalRecords} onChange={handlePageChange} />

分页相关变量

  const [page, setPage] = useState(1);
  const pageSize = 10; // 每页显示的图片数量
  const [totalRecords, setTotalRecords] = useState(0);

在 fetchData 函数中的成功回调中,使用 setPage 和 setTotalRecords来更新 page 和 totalRecords状态。这样就能确保在获取数据后及时更新这些状态。

获取数据后,设置分页信息变量

// 获取分页信息
  const pagination = responseData.pagination;
  console.log("获取分页信息 pagination: ",pagination)

  setPage(pagination.page);
  setTotalRecords(pagination.totalItems);

注意:在 Pagination 组件中,total 属性应该是总记录数。前端会根据 total 属性和每页显示的数量自动计算出分页的页数。这样做可以确保在数据更新或动态加载时,分页组件能够正确地显示页码和处理分页逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1453973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode-429.N叉树的层序遍历

题目&#xff1a; 给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。&#xff08;即从左到右&#xff0c;逐层遍历&#xff09;。 树的序列化输入是用层序遍历&#xff0c;每组子节点都由 null 值分隔&#xff08;参见示例&#xff09;。 示例 1&#xff1a; 输入&#xff…

电脑mp4格式视频打不开?别急,教你轻松解决问题

在数字化时代&#xff0c;MP4格式是广泛应用于视频存储和分享的一种常见格式。然而&#xff0c;有时候我们可能会遇到电脑mp4格式视频打不开的情况。无论您是经常处理视频的专业人士&#xff0c;还是普通用户在观看视频时遇到问题&#xff0c;接下来&#xff0c;让我们一同探索…

GPT-4助力我们突破思维定势

GPT-4在突破思维局限、激发灵感和促进知识交叉融合方面的作用不可小觑&#xff0c;它正逐渐成为一种有力的工具&#xff0c;助力各行业和研究领域的创新与发展。 GPT-4在突破传统思维模式、拓宽创新视野和促进跨学科知识融合方面扮演着越来越重要的角色&#xff1a; 突破思维…

解码成功:从8000万到110亿,鸭鸭羽绒如何练就100倍逆势增长奇迹?

鸭鸭羽绒100倍增长奇迹 在现今市场环境中&#xff0c;许多企业都面临着增长乏力的问题&#xff0c;仿佛陷入了无法突破的困境。然而&#xff0c;总有一些企业能够在这样的环境中独树一帜&#xff0c;表现出色。鸭鸭羽绒就是这样一个典型的例子。尽管整个经济环境并不理想&…

【RT-DETR有效改进】利用EMAttention加深网络深度提高模型特征提取能力(特征选择模块)

一、本文介绍 本文给大家带来的改进机制是EMAttention注意力机制,它的核心思想是,重塑部分通道到批次维度,并将通道维度分组为多个子特征,以保留每个通道的信息并减少计算开销。EMA模块通过编码全局信息来重新校准每个并行分支中的通道权重,并通过跨维度交互来捕获像素级…

CSS 故障的效果(仿抖音)

<template><!-- 创建一个视图容器,用于装载加载动画 --><view class="loader"><!-- 使用data-glitch属性存储原始文本内容,在CSS中通过attr()函数获取 --><view data-glitch="加载中..." class="glitch">加载中…

[力扣 Hot100]Day28 两数相加

题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都…

揭秘铷原子钟:北斗卫星系统的“心脏”

揭秘铷原子钟&#xff1a;北斗卫星系统的“心脏” 近日&#xff0c;中国科学院精密测量科学与技术创新研究院的梅刚华团队发布了一项重要成果。他们成功将铷原子钟的短期频率稳定度提高到了E-14&#xff08;即10的负14次方&#xff0c;相当于百万亿分之一&#xff09;的量级&a…

AMD FPGA设计优化宝典笔记(5)低频全局复位与高扇出

亚军老师的这本书《AMD FPGA设计优化宝典》&#xff0c;他主要讲了两个东西&#xff1a; 第一个东西是代码的良好风格&#xff1b; 第二个是设计收敛等的本质。 这个书的结构是一个总论&#xff0c;加上另外的9个优化&#xff0c;包含的有&#xff1a;时钟网络、组合逻辑、触发…

【JavaScript】面试手写题精讲之数组(下)

引入 这章主要讲的是数组的排序篇&#xff0c;我们知道面试的时候&#xff0c;数组的排序是经常出现的题目。所以这块还是有必要进行一下讲解的。笔者观察了下前端这块的常用算法排序题&#xff0c;大概可以分为如下 冒泡排–> 稳定排序插入排序–> 稳定排序选择排序–…

C++文件操作->文本文件(->写文件、读文件)、二进制文件(->写文件、读文件)

#include<iostream> using namespace std; #include <fstream>//头文件包含 //文本文件 写文件 void test01() { //1.包含头文件 fstream //2.创建流对象 ofstream ofs; //3.指定打开方式 ofs.open("test.txt", ios::out); //4.写…

教程10 Vue3的生命周期与方法(Typescript)+ Setup语法糖详解 + setup中的生命周期钩子(代码截图版)

一、Vue3的生命周期及在setup中的生命周期钩子 Vue官网&#xff1a;https://cn.vuejs.org/api/composition-api-lifecycle.html 在Vue3中&#xff0c;生命周期勾子函数被重新设计&#xff0c;以更好地支持组合式API的使用。 1、Vue3中的生命周期勾子函数 setup&#xff1a;…

【sql】sqlite3数据库

一、介绍 SQLite是一个轻量级的、开源的嵌入式数据库&#xff0c;由D. Richard Hipp使用C语言编写。由于其资源占用少、性能良好和零管理成本的特点&#xff0c;SQLite在嵌入式系统中得到了广泛应用&#xff0c;如Android和iPhone等操作系统中都有内置的SQLite数据库供开发人员…

华为智慧屏推出多种功能,春节期间全家一起玩乐 /腾讯广告妙思:一站式AI广告创意平台|魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525;资讯预览 华为智慧屏推出多种功能&#xff0c;春节期间全家一起玩乐 腾讯广告妙思&am…

表的操作【mysql数据库】

目录 一、创建表 二、查看表 三、修改表 改表名&#xff1a; 新增一列&#xff1a; 修改某列的属性&#xff1a; 删除某列&#xff1a; 改列名 四、删除表 一、创建表 二、查看表 desc&#xff1a;查看表的详细信息 查看建表时的详细信息&#xff1a; 三、修改表 改表…

win10下wsl2使用记录(系统迁移到D盘、配置国内源、安装conda环境、配置pip源、安装pytorch-gpu环境、安装paddle-gpu环境)

wsl2 安装好后环境测试效果如下&#xff0c;支持命令nvidia-smi&#xff0c;不支持命令nvcc&#xff0c;usr/local目录下没有cuda文件夹。 系统迁移到非C盘 wsl安装的系统默认在c盘&#xff0c;为节省c盘空间进行迁移。 1、输出wsl -l 查看要迁移的系统名称 2、执行导出命…

C#,二进制数的按位旋转(Bits Rotate)算法与源代码

1 二进制数的按位旋转 二进制数的按位旋转&#xff08;翻转&#xff09;是编程中常见的按位运算方法。 二进制数的按位旋转分为左转、右转。 左转意味着数据变大&#xff0c;右转意味着数据变小&#xff08;有损&#xff09;。 2 源程序 using System; using System.Text; us…

武汉灰京文化浅谈手游崛起的新游戏时代

随着智能手机性能的不断提升&#xff0c;手游正逐渐迈向与主机和PC游戏相媲美的领域。高性能处理器、强大的图形处理能力以及智能化技术的融合&#xff0c;使得手游可以实现更高画质和更流畅的操作体验。而虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xf…

【前端工程化面试题】webpack proxy的工作原理,为什么能解决跨域问题

在 webpack 的配置文件 webpack.config.js 中有一个配置项 devServer 里面有一个属性是 proxy&#xff0c;这里面可以配置代理服务器&#xff0c;解决跨域问题&#xff0c;请参考官网。 一般来说 webpack 的代理就是说的开发服务器 webpack-dev-server。 其实不光是 webpack 其…

Eclipse 创建 Hello World 工程

Eclipse 创建 Hello World 工程 1. Hello WorldReferences Download and install the Eclipse IDE. 1. Hello World Eclipse -> double click -> Launch 单击蓝色方框 (右上角) 最大化 IDE File -> New -> C Project -> Finish Project name&#xff1a;工程名…