React+TS前台项目实战(十五)-- 全局常用组件Table封装

文章目录

  • 前言
  • Table组件
    • 1. 功能分析
    • 2. 代码+详细注释
    • 3. 使用方式
    • 4. 效果展示
  • 总结


前言

在这篇文章中,我们将对本系列项目中常用的表格组件Table进行自定义封装,以提高性能并适应项目需求。后期也可进行修改和扩展,以满足项目的需求。


Table组件

1. 功能分析

(1)定义了两种表格项组件:TableTitleItem 和 TableContentItem
(2)TableTitleItem 用于显示表格的标题,接受 width 和 title 作为属性,将标题显示在指定宽度的行内
(3)TableContentItem 用于显示表格的内容,接受 width、content 和可选的 to 属性。如果有 to 属性,则使用全局封装的Link组件显示带有链接的内容,否则直接显示内容。
(4)使用 memo 优化组件,以提高性能并避免不必要的重新渲染
(5)可自行加下排序等功能,后续本项目有需要再加上

2. 代码+详细注释

// @/components/Table/index.tsx
import { memo, ReactNode, FC } from "react";
import { TableTitleRowItem, TableContentRowItem, HighlightLink } from "./styled";// 表格标题项组件
interface TableTitleItemProps {width: string; // 宽度title: string; // 标题
}const TableTitleItem: FC<TableTitleItemProps> = ({ width, title }) => (<TableTitleRowItem width={width}><div>{title}</div> {/* 显示标题 */}</TableTitleRowItem>
);// 表格内容项组件
interface TableContentItemProps {width: string; // 宽度content: string | ReactNode; // 内容to?: string; // 链接地址
}const TableContentItem: FC<TableContentItemProps> = ({ width, content, to }) => {return (<TableContentRowItem width={width}>{/* 如果有链接地址,则显示高亮链接,否则显示内容 */}{to ? <HighlightLink to={to}>{content}</HighlightLink> : content}</TableContentRowItem>);
};// 表格标题项组件添加memo性能优化
export const MemoizedTableTitleItem = memo(TableTitleItem);
// 表格内容项组件添加memo性能优化
export const MemoizedTableContentItem = memo(TableContentItem);--------------------------------------------------------------------------------------------------------------// @/components/Table/styled.tsx
import styled, { CSSObject } from "styled-components";
import Link from "../Link";
import variables from "@/styles/variables.module.scss";
interface ITableTitleRowItemProps {width: string;
}
interface ITableContentRowItemProps {width: string;
}
export const TableTitleRow = styled.div`background: white;display: flex;min-height: 65px;border-radius: 6px 6px 0 0;padding: 0 20px;margin-bottom: 4px;@media (max-width: ${variables.mobileBreakPoint}) {flex-flow: row wrap;min-height: auto;padding: 5px 20px;}
`;export const TableTitleRowItem = styled.div<ITableTitleRowItemProps>`display: flex;flex-direction: row;justify-content: center;align-items: center;width: ${({ width }) => width};min-height: 65px;div,button {border: none;outline: none;background-color: transparent;color: #333;font-size: 18px;font-weight: 450;text-align: center;@media (max-width: ${variables.largeBreakPoint}) {font-size: 16px;}}@media (max-width: ${variables.mobileBreakPoint}) {margin: 10px 40px 10px 0;min-height: auto;}
`;export const TableContentRow = styled.div`position: relative;display: flex;min-height: 60px;background-color: white;padding: 20px;::after {content: "";position: absolute;display: block;width: auto;height: 1px;left: 20px;right: 20px;bottom: 1px;background: #d8d8d8;transform: ${(): CSSObject => ({scaleY: `${Math.ceil((1.0 / window.devicePixelRatio) * 10.0) / 10.0}`,})};}:hover {background: #f8f9fa;}
`;export const TableContentRowItem = styled.div<ITableContentRowItemProps>`width: ${({ width }) => width};color: #000;display: flex;align-items: center;justify-content: center;text-overflow: ellipsis;font-size: 16px;a {color: ${({ theme }) => theme.primary};&:hover {color: ${({ theme }) => theme.primary};}}
`;export const HighlightLink = styled(Link)`color: ${({ theme }) => theme.primary};text-decoration: none;
`;

3. 使用方式

注:这个组件我们模拟一些假数据来演示,可直接复制代码看效果

// @/pages/Nav1/styled.tsx
// 引入组件
import { MemoizedTableContentItem } from "@/components/Table";
// 使用
import { FC, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import Content from "@/components/Content";
import { TableTitleRow, TableContentRow, TableTitleRowItem } from "@/components/Table/styled";
import { BlockListPanel, ContentTable } from "./styled";
import { useMediaQuery } from "@/hooks";
import { localeNumberString } from "@/utils/number";
interface TableTitleData {title: string; // 表头名称width: string; // 表头宽度
}
interface Block {number: number; // 块高row1Content?: string; // 第一行内容row2Content?: string; // 第二行内容row3Content?: string; // 第三行内容row4Content?: string; // 第四行内容width: string; // 表行宽度to?: string; // 链接
}
interface TableContentData {width: string; // 表格列宽度to?: string; // 链接content: string; // 表格内容
}
const Nav2Page: FC = () => {const [t] = useTranslation();const isMaxW = useMediaQuery(`(max-width: 1200px)`);const TableTitles: TableTitleData[] = useMemo(() => [{title: "Row1",width: isMaxW ? "16%" : "14%",},{title: "Row2",width: isMaxW ? "18%" : "11%",},{title: "Row3",width: "20%",},{title: "Row4",width: isMaxW ? "33%" : "40%",},{title: "Row5",width: isMaxW ? "13%" : "15%",},],[t, isMaxW]);// 表格数据const [tableData] = useState([{number: 99663.6333663333,row1Content: "row1内容",row2Content: "row2内容",row3Content: "row3内容",row4Content: "row4内容",width: "16%",to: "/Nav3",},// ...]);// 当前页const currentPage = 1;// 每页数据const transferToRowData = (block: Block, page: number, isMaxW: boolean) => {return [{width: isMaxW ? "16%" : "14%",to: `/block/${block.number}`,content: localeNumberString(block.number),},{width: isMaxW ? "18%" : "11%",content: block.row1Content,},{width: "20%",content: block.row2Content,},{width: isMaxW ? "33%" : "40%",content: block.row3Content,},{width: isMaxW ? "13%" : "15%",content: block.row4Content,},] as TableContentData[];};return (<Content><BlockListPanel className="container"><ContentTable>{/* 表头 */}<TableTitleRow>{TableTitles.map((data: TableTitleData) => (<TableTitleRowItem width={data.width} key={data.title}><div>{data.title}</div></TableTitleRowItem>))}</TableTitleRow>{/* 表内容 */}{tableData.map((item: Block) =>item && (<TableContentRow key={item.number}>{transferToRowData(item, currentPage, isMaxW).map((data: TableContentData) => {return <MemoizedTableContentItem width={data.width} content={data.content} to={data.to} />;})}</TableContentRow>))}</ContentTable></BlockListPanel></Content>);
};
export default Nav2Page;--------------------------------------------------------------------------------------------------------------// @/pages/Nav1/styled.tsx
import styled from "styled-components";
import variables from "@/styles/variables.module.scss";
export const BlockListPanel = styled.div`@media (min-width: ${variables.mobileBreakPoint}) {margin-top: 25px;margin-bottom: 40px;border-radius: 6px;overflow: hidden;box-shadow: 0 2px 6px 0 rgb(77 77 77 / 21%);}@media (max-width: ${variables.mobileBreakPoint}) {margin-top: 0;padding: 0 20px;.blockGreenBackground {margin-left: -20px;height: 61px;width: calc(100% + 40px);z-index: 1;}}
`;export const ContentTitle = styled.div`font-size: 50px;color: black;margin: 0 auto;text-align: center;@media (max-width: ${variables.mobileBreakPoint}) {font-size: 26px;}&::after {content: "";background: ${({ theme }) => theme.primary};height: 4px;width: 197px;display: block;margin: 0 auto;@media (max-width: ${variables.mobileBreakPoint}) {width: 80px;}}
`;export const ContentTable = styled.div`@media (max-width: ${variables.mobileBreakPoint}) {margin-top: -41px;z-index: 2;}
`;

4. 效果展示

在这里插入图片描述


总结

下一篇讲【全局常用组件Pagination封装】。关注本栏目,将实时更新。

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

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

相关文章

C# Onnx Yolov5 水果识别,人员识别,物品识别 人工智能

目录 先上效果 来电废话&#xff0c;但实用 网络成功案例实践易失败的原因 万物检测涉及技术 下载合集 关键代码 全部代码 实操vs2022安装关键 YOLO V5核心库编译 编写自己识别软件 更新相关依赖 标注字库文件 测试效果 名词解释YOLO 名词解释ONNX 源码 直播教…

卸载 ubuntu-wsl2-systemd-script,使用 WSLg 图形用户界面

目录 全新安装 - 以前没有安装 WSL现有 WSL 安装卸载 ubuntu-wsl2-systemd-script使用 Linux GUI参考链接在 Windows 上使用 Linux 开发环境,最好的做法是使用 WSL2。在 WSL 和早期的 WSL2 版本中,并不支持图形用户界面。因此如果想要使用 GUI 程序,需要自行解决。具体方法可…

读线圈和离散状态寄存器信息

一.功能码操作类型 二.读线圈状态 需求实例 读取设备地址为 3 的从设备的线圈状态寄存器&#xff0c;线圈地址为 19 到 55&#xff08;从 0 开始计算&#xff09;共 37 个状态。 分析&#xff1a;由需求可知读取地址&#xff0c;则功能码是0x01,地址为3即为0x03,线圈地址为19到…

Python | Leetcode Python题解之第179题最大数

题目&#xff1a; 题解&#xff1a; class Solution:def largestNumber(self, nums: List[int]) -> str:def quick_sort(l , r):if l > r: returni, j l, rwhile i < j:while strs[j] strs[l] > strs[l] strs[j] and i < j: j - 1while strs[i] strs[l] &l…

基于matlab的BP神经网络分类预测

1.神经网络结构 本文网络结构如图1所示&#xff1a; 图1 网络结构 图1给出的并不是单纯的bp神经网络结构这里设置了三个隐藏层&#xff0c;神经元个数分别为6&#xff0c;3&#xff0c;3&#xff0c;输入层12个特征输入&#xff0c;输出层输出4个类型结果。 2.代码 %% 清空环…

使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 )

</com.xujun.drawerLayout.drag.DragLayout> 在代码中若想为其设置监听器, 分别可以监听打开的 时候&#xff0c;关闭的时候&#xff0c;拖动的时候&#xff0c;可以在里面做相应的处理&#xff0c;同时我还加入了 自定义属性可以通过 app:range”480”或者setRange&am…

嵌入式linux系统中LCD屏驱动实现思路分析

在 Linux 下 LCD 的使用更加广泛,在搭配 QT 这样的 GUI 库下可以制作出非常精美的 UI 界面。接下来就来学习一下如何在 Linux 下驱动 LCD 屏幕。 第一:Framebuffer设备简介 先来回顾一下裸机的时候 LCD 驱动是怎么编写的,裸机 LCD 驱动编写流程如下: ①、初始化 I.MX6U 的…

Selenium WebDriver - 网络元素

本文翻译整理自&#xff1a;https://www.selenium.dev/documentation/webdriver/elements/ 文章目录 一、文件上传二、定位策略1、传统定位器2、创建定位器3、类名4、CSS选择器5、id6、NAME7、链接文本8、部分链接文本9、标签名称10、xpath11、相对定位器它是如何工作的可用相对…

three.js 第八节 - gltf加载器、解码器

// ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入hdr加载器&#xff08;专门加载hdr的&#xff09; import { RGBELoader } from three/examples/jsm/loaders…

npm全局安装依赖指定存放文件目录

引言 学校机房&#xff0c;每次默认在c盘装完 电脑关机重启都得重新安装&#xff0c;十分麻烦 1-创建依赖安装/缓存目录 2-打开终端输入设置安装目录位置的命令 npm set cache \你创建的缓存文件目录\ npm set prefix \你创建的global全局安装依赖文件目录\至此以后npm -g 依…

自动驾驶仿真Carla -ACC功能测试

我将详细说明如何使用Carla进行ACC&#xff08;自适应巡航控制&#xff09;测试&#xff0c;确保每个步骤贴合实际的Carla自动驾驶仿真标准&#xff0c;并提供相应的代码示例。 使用Carla进行ACC测试的步骤&#xff1a; 1. 环境设置和启动Carla 首先&#xff0c;确保你已经安装…

巴鲁夫MacroBuilder2.0.0.0软件巴鲁夫和使用手侧

巴鲁夫MacroBuilder2.0.0.0软件巴鲁夫和使用手侧

Linux下多进程访问同一个共享库处理流程

两个测试程序实现调用同一个SO库: ​​​​​​​ #include <stdio.h> #include "a/a.h" #include <unistd.h> int main() { int a = 4,b = 5; sum(a, b); int ret = get(); printf("ret=%d\n", ret); sleep(100)…

数据库新技术【分布式数据库】

文章目录 第一章 概述1.1 基本概念1.1.1 分布式数据库1.1.2 数据管理的透明性1.1.3 可靠性1.1.4 分布式数据库与集中式数据库的区别 1.2 体系结构1.3 全局目录1.4 关系代数1.4.1 基操1.4.2 关系表达式1.4.3 查询树 第二章 分布式数据库的设计2.1 设计策略2.2 分布设计的目标2.3…

【Linux】基础IO_2

文章目录 六、基础I/O2. 系统文件I/O磁盘的存储结构 未完待续 六、基础I/O 2. 系统文件I/O 磁盘的存储结构 系统中不是所有对文件都是打开的状态&#xff0c;大部分的文件都是没有被打开的。这些文件一般都被存储在磁盘当中。磁盘通过柱面&#xff0c;扇面&#xff0c;扇区确…

Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案

初始化数据 */ private void initData(Bundle savedInstanceState) { if (savedInstanceState ! null) mDatas savedInstanceState.getStringArrayList(“mDatas”); if (mDatas null) { mLoadingDialog new LoadingDialog(); mLoadingDialog.show(getFragmentMana…

Renesas MCU使用定时器之实现1ms定时中断

目录 概述 1 软硬件介绍 1.1 软件版本信息 1.2 硬件介绍 2 FSP配置项目 2.1 项目参数配置 2.2 配置定时器参数 3 功能实现 3.1 软件架构实现 3.2 实现功能函数 4 测试 概述 本文主要介绍使用Renesas MCU定时器之实现1ms定时中断功能&#xff0c;文中介绍使用FSP配…

理解 iOS 开发中的 NS_ENUM 和 NS_OPTIONS

在开发 iOS 应用程序时&#xff0c;理解 NS_ENUM 和 NS_OPTIONS 的使用至关重要&#xff0c;因为它们在定义和管理枚举和选项方面起着重要作用。在本文中&#xff0c;我们将深入探讨 NS_ENUM 和 NS_OPTIONS 之间的区别、使用场景以及如何有效地实现它们。 NS_ENUM NS_ENUM 用…

对兼容各操作系统的Anki选择题模板的更新——提供更方便的笔记修改功能

2021年当我想做一个兼容各操作系统的Anki选择题模板的时候&#xff0c;到处搜索茧中网&#xff0c;根本找不到相关内容&#xff0c;直到偶然在github上看到Simon Lammer的Anki持久化模块&#xff0c;才算真正实现。现在再在茧中网上搜索兼容各种操作系统的Anki选择题模板&#…

Android蓝牙开发(一)之打开蓝牙和设备搜索

private BluetoothManager bluetoothmanger; private​ BluetoothAdapter bluetoothadapter; /** 判断设备是否支持蓝牙 */ bluetoothmanger (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothadapter bluetoothmanger.getAdapter(); if (bl…