React封装通用Table组件,支持搜索(多条件)、筛选、自动序号、数据量统计等功能。未采用二次封装调整灵活,包含使用文档

封装通用组件

  • 一、封装思想
  • 二、react代码
  • 三、css代码
  • 四、实现效果
  • 五、使用文档 BasicTableModal 表格模态框组件
    • 1.组件简介
    • 2.功能特点
    • 3.使用方法
      • 基础用法
      • 宽度控制示例
      • 带筛选功能
      • 搜索功能示例
      • 自定义单元格渲染
    • 4.API 说明
      • Props
      • Column 配置项
      • Filter 配置项
    • 5.注意事项

一、封装思想

1.通用性:可以适用于多种表格展示场景,样式设计更灵活
2.可配置性:提供丰富的配置选项
3.易用性:使用方式简单直观
4.可维护性:代码结构清晰,逻辑分明
5.可扩展性:预留了自定义渲染等扩展接口

二、react代码

import React from 'react';
import PropTypes from 'prop-types'; // 通过PropTypes实现数据校验
import 'src/css/basicTableModal.css';class BasicTableModal extends React.Component {constructor(props) {super(props);this.state = {searchText: '',filterValues: {},filteredData: props.data || [],visible: props.visible || false};}// 添加序号列到columns中getColumnsWithIndex = () => {const indexColumn = {key: '_index',title: '序号',render: (text, record, index) => index + 1};return [indexColumn, ...this.props.columns];}componentDidMount() {this.filterAndSearchData();}componentDidUpdate(prevProps) {if (prevProps.data !== this.props.data) {this.filterAndSearchData();}if (prevProps.visible !== this.props.visible) {this.setState({ visible: this.props.visible });}}// 处理搜索和筛选filterAndSearchData = () => {const { data, searchableKeys = [] } = this.props;const { searchText, filterValues } = this.state;let result = [...data];// 处理搜索if (searchText.trim()) {result = result.filter(item => {return searchableKeys.some(key => {const cellValue = item[key];return cellValue && String(cellValue).toLowerCase().includes(searchText.toLowerCase());});});}// 处理筛选Object.entries(filterValues).forEach(([key, value]) => {if (value) {result = result.filter(item => item[key] === value);}});this.setState({ filteredData: result });}handleSearchChange = (e) => {this.setState({ searchText: e.target.value }, this.filterAndSearchData);}handleFilterChange = (key, value) => {this.setState(prevState => ({filterValues: {...prevState.filterValues,[key]: value}}), this.filterAndSearchData);}handleClose = () => {const { onClose } = this.props;this.setState({ visible: false });if (onClose) {onClose();}}// 渲染筛选下拉框renderFilterDropdown = (column) => {if (!column.filters) return null;return (<selectclassName="filter-select"value={this.state.filterValues[column.key] || ''}onChange={(e) => this.handleFilterChange(column.key, e.target.value)}><option value="">全部</option>{column.filters.map((filter, index) => (<option key={index} value={filter.value}>{filter.text}</option>))}</select>);}render() {const { title, searchPlaceholder = "输入关键字搜索...", width } = this.props;const { searchText, filteredData, visible } = this.state;const columnsWithIndex = this.getColumnsWithIndex();if (!visible) return null;const modalStyle = {width: width || '80%',maxWidth: '1000px'};return (<div className="modal-overlay"><div className="modal-content" style={modalStyle}><div className="modal-header"><h3>{title || '表格详情'}</h3><button className="close-button" onClick={this.handleClose}>×</button></div><div className="basic-table-container"><div className="table-toolbar">{(this.props.searchableKeys && this.props.searchableKeys.length > 0) && (<inputtype="text"placeholder={searchPlaceholder}value={searchText}onChange={this.handleSearchChange}className="search-input"/>)}<div className="filter-container">{this.props.columns.map(column => (column.filters && (<div key={column.key} className="filter-item"><span className="filter-label">{column.title}:</span>{this.renderFilterDropdown(column)}</div>)))}</div></div><div className="table-content-wrapper"><table className="basic-table"><thead><tr>{columnsWithIndex.map(column => (<th key={column.key} style={{ width: column.width || 'auto' }}>{column.title}</th>))}</tr></thead><tbody>{filteredData.map((item, index) => (<tr key={index} className={index % 2 === 0 ? 'table-row-light' : 'table-row-dark'}>{columnsWithIndex.map(column => (<td key={column.key} style={{ width: column.width || 'auto' }}>{column.render ? column.render(item[column.key], item, index) : item[column.key]}</td>))}</tr>))}</tbody></table></div><div className="table-footer"><span className="data-count">数量({filteredData.length})</span></div></div></div></div>);}
}// 数据格式校验
BasicTableModal.propTypes = {columns: PropTypes.arrayOf(PropTypes.shape({key: PropTypes.string.isRequired,title: PropTypes.string.isRequired,render: PropTypes.func,width: PropTypes.oneOfType([PropTypes.number,PropTypes.string]),filters: PropTypes.arrayOf(PropTypes.shape({text: PropTypes.string.isRequired,value: PropTypes.any.isRequired}))})).isRequired,data: PropTypes.array.isRequired,visible: PropTypes.bool,onClose: PropTypes.func,title: PropTypes.string,searchableKeys: PropTypes.arrayOf(PropTypes.string),searchPlaceholder: PropTypes.string,width: PropTypes.oneOfType([PropTypes.number,PropTypes.string])
};BasicTableModal.defaultProps = {data: [],visible: false,searchableKeys: [],width: '80%'
};export default BasicTableModal;

三、css代码

/* 模态框基础样式
-------------------------------------------------- */
.modal-overlay {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;z-index: 1000;
}.modal-content {background-color: white;border-radius: 4px;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);max-height: 90vh;display: flex;flex-direction: column;position: relative;
}/* 模态框头部样式
-------------------------------------------------- */
.modal-header {background-color: #eaeaea;border-bottom: 1px solid #e8e8e8;display: flex;justify-content: space-between;align-items: center;position: relative;border-radius: 4px 4px 0 0;
}.modal-header::before {content: '';position: absolute;top: 9px;left: 10px;height: 14px;border-left: 2px solid #f95e34;
}.modal-header h3 {margin: 0;font-size: 12px;font-family: Microsoft Yahei;color: rgba(0, 0, 0, 0.85);margin-left: 15px;
}.close-button {background: none !important;cursor: pointer;line-height: 33px;
}/* 表格容器布局
-------------------------------------------------- */
.basic-table-container {padding: 5px;flex: 1;display: flex;flex-direction: column;min-height: 0;position: relative;
}.table-content-wrapper {overflow: auto;flex: 1;min-height: 0;
}/* 表格基础样式
-------------------------------------------------- */
.basic-table {width: 100%;border-collapse: separate;border-spacing: 0;background-color: #fff;font-size: 12px;font-family: Microsoft Yahei;line-height: 0.5;
}.basic-table th,
.basic-table td {padding: 12px 8px;border: 1px solid #e8e8e8;text-align: left;
}/* 表格头部样式
-------------------------------------------------- */
.basic-table thead {position: sticky;top: 0;z-index: 2;background-color: #fafafa;
}.basic-table th {background-color: #fafafa;font-weight: 500;box-shadow: 0 1px 0 #e8e8e8;
}/* 表格内容样式
-------------------------------------------------- */
.basic-table tbody {overflow-y: auto;
}.table-row-light {background-color: #f0f0f0;
}.table-row-dark {background-color: #ffffff;
}/* 滚动条样式
-------------------------------------------------- */
.basic-table-container::-webkit-scrollbar {display: none;
}.table-content-wrapper::-webkit-scrollbar {width: 4px;height: 8px;
}.table-content-wrapper::-webkit-scrollbar-thumb {background-color: #c1c1c1;border-radius: 20px;transition: background-color 0.3s;
}.table-content-wrapper::-webkit-scrollbar-thumb:hover {background-color: #a8a8a8;
}.table-content-wrapper::-webkit-scrollbar-track {background: #f1f1f1;border-radius: 20px;
}.table-content-wrapper::-webkit-scrollbar-corner {background: transparent;
}/* 工具栏样式
-------------------------------------------------- */
.table-toolbar {display: flex;align-items: center;padding: 8px;gap: 16px;position: sticky;top: 0;background-color: white;z-index: 1;border-bottom: 1px solid #e8e8e8;
}/* 搜索框样式
-------------------------------------------------- */
.search-input {min-width: 200px;max-width: 300px;height: 28px;padding: 4px 8px;border: 1px solid #d9d9d9;border-radius: 2px;font-size: 12px;
}.search-input:focus {border-color: #f95e34;outline: none;box-shadow: 0 0 0 2px rgba(249, 94, 52, 0.2);
}/* 筛选器样式
-------------------------------------------------- */
.filter-container {display: flex;align-items: center;gap: 12px;flex-wrap: wrap;
}.filter-item {display: flex;align-items: center;gap: 4px;
}.filter-label {font-size: 12px;color: rgba(0, 0, 0, 0.85);
}.filter-select {height: 28px;padding: 4px 8px;border: 1px solid #d9d9d9;border-radius: 2px;font-size: 12px;min-width: 100px;
}.filter-select:focus {border-color: #f95e34;outline: none;box-shadow: 0 0 0 2px rgba(249, 94, 52, 0.2);
}/* 表格底部样式
-------------------------------------------------- */
.table-footer {padding: 8px;display: flex;align-items: center;position: sticky;bottom: 0;background-color: white;z-index: 1;border-top: 1px solid #e8e8e8;
}.data-count {font-size: 12px;color: rgba(0, 0, 0, 0.65);font-family: Microsoft Yahei;
} 

四、实现效果

在这里插入图片描述

五、使用文档 BasicTableModal 表格模态框组件

1.组件简介

BasicTableModal 是一个表格模态框组件,提供了搜索、筛选、自动序号、数据量统计等功能。它适用于需要在模态框中展示表格数据的场景。

2.功能特点

  • 支持表格数据展示
  • 自动添加序号列
  • 支持关键字搜索
  • 支持多列筛选
  • 支持自定义单元格渲染
  • 支持奇偶行样式区分
  • 响应式设计
  • 支持数据量统计显示
  • 支持模态框宽度自定义
  • 支持列宽自定义

3.使用方法

基础用法

import BasicTableModal from './basicTableModal';const columns = [{key: 'name',title: '姓名'},{key: 'age',title: '年龄'}
];const data = [{ name: '张三', age: 25 },{ name: '李四', age: 30 }
];function MyComponent() {return (<BasicTableModal columns={columns}data={data}visible={true}onClose={() => {}}/>);
}

宽度控制示例

// 设置模态框宽度
<BasicTableModal width="90%"columns={columns}data={data}
/>// 设置列宽度
const columns = [{key: 'index',title: '序号',width: 80  // 固定像素宽度},{key: 'name',title: '姓名',width: '150px'  // 带单位的宽度},{key: 'description',title: '描述',width: '40%'  // 百分比宽度}
];

带筛选功能

const columns = [{key: 'name',title: '姓名'},{key: 'status',title: '状态',filters: [{ text: '在线', value: 'online' },{ text: '离线', value: 'offline' }]}
];

搜索功能示例

// 多字段组合搜索示例
const columns = [{key: 'name',title: '姓名'},{key: 'code',title: '编号'},{key: 'description',title: '描述'}
];<BasicTableModal columns={columns}data={data}searchableKeys={['name', 'code', 'description']}  // 可以同时搜索多个字段searchPlaceholder="输入姓名/编号/描述搜索..."
/>

自定义单元格渲染

const columns = [{key: 'name',title: '姓名',render: (text, record, index) => <span style={{color: 'red'}}>{text}</span>}
];

4.API 说明

Props

参数说明类型必填默认值
columns表格列配置Array-
data表格数据Array[]
visible是否显示模态框booleanfalse
onClose关闭模态框的回调函数function-
title模态框标题string‘表格详情’
searchableKeys可搜索的字段键名数组string[][]
searchPlaceholder搜索框占位文本string‘输入关键字搜索…’
width模态框宽度number/string‘80%’

Column 配置项

参数说明类型必填默认值
key列数据对应的键名string-
title列标题string-
render自定义渲染函数function(text, record, index)-
filters筛选选项配置Array-
width列宽度number/string‘auto’

Filter 配置项

参数说明类型必填
text筛选项显示文本string
value筛选项对应的值any

5.注意事项

  1. 组件会自动在表格最左侧添加序号列
  2. 搜索功能仅在设置 searchableKeys 且不为空数组时显示搜索框
  3. 筛选和搜索可以同时使用
  4. 表格支持奇偶行样式区分,便于数据查看
  5. 模态框宽度可以使用数字(默认像素)或带单位的字符串(如:‘80%’、‘800px’)
  6. 列宽度同样支持数字和带单位的字符串,不设置时自动适应内容宽度
  7. 数据总量显示会实时反映当前筛选/搜索后的数据条数

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

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

相关文章

React 中 useState 的 基础使用

概念&#xff1a;useState 是一个React Hook&#xff08;函数&#xff09;&#xff0c;它允许我们向组件添加状态变量&#xff0c;从而影响组件的渲染结果。 本质&#xff1a;和普通JS变量不同的是&#xff0c;状态变量一旦发生变化&#xff0c;组件的视图UI也会跟着变化&…

Html5学习教程,从入门到精通,HTML `<div>` 和 `<span>` 标签:语法知识点与案例代码(12)

HTML <div> 和 <span> 标签&#xff1a;语法知识点与案例代码 一、语法知识点 1. <div> 标签 定义: <div> 是一个块级元素&#xff0c;用于将文档内容划分为独立的、可样式化的部分。它本身没有特定的语义&#xff0c;主要用于布局和分组。特点: 块…

Hbase伪分布安装教程,详细版

注意Hbase版本与Hadoop版本的兼容&#xff0c;还有与JDK版本的兼容 本次用到的Hbase为2.4.6版本&#xff0c;Hadoop为3.1.3版本&#xff0c;JDK为JDK8 打开下面的网址查看兼容问题 Apache HBase Reference Guidehttps://hbase.apache.org/book.html#configuration 点击基础先…

Python项目】基于Python的图像去雾算法研究和系统实现

Python项目】基于Python的图像去雾算法研究和系统实现 技术简介&#xff1a;采用Python技术、MYSQL数据库等实现。 系统简介&#xff1a;图像去雾系统主要是基于暗通道先验和逆深度估计技术的去雾算法&#xff0c;系统功能模块分为&#xff08;1&#xff09;图像上传模块&…

Stable Diffusion Prompt编写规范详解

Stable Diffusion Prompt编写规范详解 一、语法结构规范 &#xff08;一&#xff09;基础模板框架 [质量强化] [主体特征] [环境氛围] [风格控制] [镜头参数]质量强化&#xff1a;best quality, ultra detailed, 8k resolution‌主体特征&#xff1a;(1girl:1.3), long …

勿以危小而为之勿以避率而不为

《故事汇之&#xff1a;所见/所闻/所历/所想》&#xff1a;《公园散步与小雨遇记》&#xff08;二&#xff09; 就差一点到山顶了&#xff0c;路上碰到一阿姨&#xff0c;她说等会儿要下大雨了&#xff0c;让我不要往上走了&#xff0c;我犹豫了一会儿&#xff0c;还是听劝地返…

wheel_legged_genesis 开源项目复现与问题记录

Reinforcement learning of wheel-legged robots based on Genesis System Requirements Ubuntu 20.04/22.04/24.04 python > 3.10 开始配置环境&#xff01; 点击releases后进入&#xff0c;下载对应最新版本的代码&#xff1a; 将下载后的代码包解压到你的自定义路径下&…

Gin框架从入门到实战:核心用法与最佳实践

为什么选择Gin框架&#xff1f; Gin 是一个基于 Go 语言的高性能 Web 框架&#xff0c;具备以下优势&#xff1a; 轻量高效&#xff1a;底层依赖 net/http&#xff0c;性能接近原生。简洁优雅&#xff1a;API 设计友好&#xff0c;支持路由分组、中间件链、参数绑定等特性。生…

Leetcode 3468. Find the Number of Copy Arrays

Leetcode 3468. Find the Number of Copy Arrays 1. 解题思路2. 代码实现 题目链接&#xff1a;3468. Find the Number of Copy Arrays 1. 解题思路 这一题的话思路上就是一个范围考察&#xff0c;显然&#xff0c;对于指定的copy方式&#xff0c;只要我们确定了第一个元素&…

VirtualBox虚拟机MacOS从Big Sur升级到Sequoia(失败)

VirtualBox虚拟机里安装好Big Sur版本&#xff0c;尝试升级到Sequoia&#xff0c;但是最终失败了。 软件升级 直接在系统偏好-软件更新里可以看到提示&#xff0c;提示可以升级到15版本Sequoia 点击同意&#xff0c;看能不能升级到Sequoia吧。升级前先用时光做了备份。 升级…

[杂学笔记]HTTP1.0和HTTP1.1区别、socket系列接口与TCP协议、传输长数据的时候考虑网络问题、慢查询如何优化、C++的垃圾回收机制

目录 1.HTTP1.0和HTTP1.1区别 2.socket系列接口与TCP协议 3.传输长数据的时候考虑网络问题 4.慢查询如何优化 5.C的垃圾回收机制 1.HTTP1.0和HTTP1.1区别 在连接方式上&#xff0c;HTTP1.0默认采用的是短链接的方式&#xff0c;就建立一次通信&#xff0c;也就是说即使在…

ANI AGI ASI的区别

‌‌ANI、‌AGI、‌ASI的区别主要体现在定义、特点和应用场景上‌&#xff1a; 1. ANI&#xff08;狭义人工智能 Artificial narrow intelligence&#xff09;‌&#xff1a; ‌定义‌&#xff1a;ANI&#xff0c;也被称为弱人工智能&#xff0c;是指专门设计用于执行特定任务…

用OpenCV写个视频播放器可还行?(Python版)

引言 提到OpenCV&#xff0c;大家首先想到的可能是图像处理、目标检测&#xff0c;但你是否想过——用OpenCV实现一个带进度条、倍速播放、暂停功能的视频播放器&#xff1f;本文将通过一个实战项目&#xff0c;带你深入掌握OpenCV的视频处理能力&#xff0c;并解锁以下功能&a…

leetcode日记(77)子集Ⅱ

不知道为什么看到这道题就很头痛…… 其实只要掌握nums不包含重复元素的情况下的代码就行了。 若nums不能包含重复元素&#xff0c;那么使用回溯很容易就能写出来&#xff1a; class Solution {void hs(vector<int> v,int x,vector<int> r,vector<vector<…

通俗版解释:分布式和微服务就像开餐厅

一、分布式系统&#xff1a;把大厨房拆成多个小厨房 想象你开了一家超火爆的餐厅&#xff0c;但原来的厨房太小了&#xff1a; 问题&#xff1a;一个厨师要同时切菜、炒菜、烤面包&#xff0c;手忙脚乱还容易出错。 解决方案&#xff1a; 拆分成多个小厨房&#xff08;分布式…

StarRocks-fe工程在Cursor中不能识别为Java项目

SR简介 StarRocks 是一款高性能分析型数据库&#xff0c;支持实时、多维度、高并发的数据分析。本指南旨在解决在使用 VSCode 或 Cursor 开发 StarRocks 后端项目时遇到的模块识别问题。 问题描述 使用 Cursor 或 VSCode 打开 StarRocks 的后端工程 fe 时&#xff0c;spark-…

第五节:基于Winform框架的串口助手小项目---串口收发《C#编程》

“路漫漫其修远兮&#xff0c;吾将上下而求索” &#xff0c; -----------------------WHAPPY 目标任务&#xff1a; 1 从本地设备列表获取串口。 RegistryKey keyCom Registry.LocalMachine.OpenSubKey("Hardware\DeviceMap\SerialComm"); RegistryKey 是.NET 框…

专题二最大连续1的个数|||

1.题目 题目分析&#xff1a; 给一个数字k&#xff0c;可以把数组里的0改成1&#xff0c;但是只能改k次&#xff0c;然后该变得到的数组能找到最长的子串且都是1。 2.算法原理 这里不用真的把0变成1&#xff0c;因为改了比较麻烦&#xff0c;下次用就要改回成1&#xff0c;这…

25年第四本【认知觉醒】

《认知觉醒》&#xff1a;一场与大脑的深度谈判 在信息爆炸的焦虑时代&#xff0c;我们像被抛入湍流的溺水者&#xff0c;拼命抓取各种自我提升的浮木&#xff0c;却在知识的漩涡中越陷越深。这不是一本简单的成功学指南&#xff0c;而是一场关于人类认知系统的深度对话&#…

甘特图开发代码(测试版)

场景&#xff1a;要实现的功能就是单行数据能左右拖动。 流程五个&#xff1a;ABCDE。&#xff08;对应&#xff1a;Charter开发、概念和计划、初样开发、正样开发、验证&#xff09; 1、A有开始时间&#xff0c;结束时间。B的开始时间必须是A的结束时间&#xff08;相等或者…