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 | 是否显示模态框 | boolean | 否 | false |
| 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.注意事项
- 组件会自动在表格最左侧添加序号列
- 搜索功能仅在设置 searchableKeys 且不为空数组时显示搜索框
- 筛选和搜索可以同时使用
- 表格支持奇偶行样式区分,便于数据查看
- 模态框宽度可以使用数字(默认像素)或带单位的字符串(如:‘80%’、‘800px’)
- 列宽度同样支持数字和带单位的字符串,不设置时自动适应内容宽度
- 数据总量显示会实时反映当前筛选/搜索后的数据条数
相关文章:
React封装通用Table组件,支持搜索(多条件)、筛选、自动序号、数据量统计等功能。未采用二次封装调整灵活,包含使用文档
封装通用组件 一、封装思想二、react代码三、css代码四、实现效果五、使用文档 BasicTableModal 表格模态框组件1.组件简介2.功能特点3.使用方法基础用法宽度控制示例带筛选功能搜索功能示例自定义单元格渲染 4.API 说明PropsColumn 配置项Filter 配置项 5.注意事项 一、封装思…...
【JavaEE】-- 多线程(初阶)4
文章目录 8.多线程案例8.1 单例模式8.1.1 饿汉模式8.1.2 懒汉模式 8.2 阻塞队列8.2.1 什么是阻塞队列8.2.2 生产者消费者模型8.2.3 标准库中的阻塞队列8.2.4 阻塞队列的应用场景8.2.4.1 消息队列 8.2.5 异步操作8.2.5 自定义实现阻塞队列8.2.6 阻塞队列--生产者消费者模型 8.3 …...
WP 高级摘要插件:助力 WordPress 文章摘要精准自定义显示
wordpress插件介绍 “WP高级摘要插件”功能丰富,它允许用户在WordPress后台自定义文章摘要。 可设置摘要长度,灵活调整展示字数;设定摘要最后的显示字符, 如常用的省略号等以提示内容未完整展示;指定允许在摘要中显示…...
论文阅读 EEG-Inception
EEG-Inception: A Novel Deep Convolutional Neural Network for Assistive ERP-Based Brain-Computer Interfaces EEG-Inception是第一个集成Inception模块进行ERP检测的模型,它有效地结合了轻型架构中的其他结构,提高了我们方法的性能。 本研究的主要目…...
FFmpeg入门:最简单的音频播放器
FFmpeg入门:最简单的音频播放器 欢迎大家来到FFmpeg入门的第二章,今天只做一个最简单的FFmpeg音频播放器;同样,话不多说,先上流程图 流程图 以上流程和视频播放器的解码过程基本上是一致的; 不同点在于 S…...
物联网感应层数据采集器实现协议转换 数据格式化
数据采集器的核心功能实现涉及多个技术层面的协同工作,以下是各模块的详细实现解析: 协议转换实现 协议解析引擎:采用插件式架构,例如: P r o t o c o l P a r...
基于Linux系统的物联网智能终端
背景 产品研发和项目研发有什么区别?一个令人发指的问题,刚开始工作时项目开发居多,认为项目开发和产品开发区别不大,待后来随着自身能力的提升,逐步感到要开发一个好产品还是比较难的,我认为项目开发的目的…...
8.1.STM32_OLED
4.STM32_OLED 跟着江协科大的视频,无法点亮OLED屏幕解决办法 每个人使用的0.96寸OLED屏幕信号不一样,存在很多兼容性问题 归根结底就是驱动的问题! 本人的OLED是SSD1306,在淘宝店铺找了驱动文件后成功点亮,示例见文末 请针对自…...
Netty笔记9:粘包半包
Netty笔记1:线程模型 Netty笔记2:零拷贝 Netty笔记3:NIO编程 Netty笔记4:Epoll Netty笔记5:Netty开发实例 Netty笔记6:Netty组件 Netty笔记7:ChannelPromise通知处理 Netty笔记8…...
【算法方法总结·三】滑动窗口的一些技巧和注意事项
【算法方法总结三】滑动窗口的一些技巧和注意事项 【算法方法总结一】二分法的一些技巧和注意事项【算法方法总结二】双指针的一些技巧和注意事项【算法方法总结三】滑动窗口的一些技巧和注意事项 【滑动窗口】 数组的和 随着 右边指针 移动一定是 非递减 的,就是 …...
LabVIEW虚拟弗兰克赫兹实验仪
随着信息技术的飞速发展,虚拟仿真技术已经成为教学和研究中不可或缺的工具。开发了一种基于LabVIEW平台开发的虚拟弗兰克赫兹实验仪,该系统不仅能模拟实验操作,还能实时绘制数据图形,极大地丰富了物理实验的教学内容和方式。 …...
spring boot + vue 搭建环境
参考文档:https://blog.csdn.net/weixin_44215249/article/details/117376417?fromshareblogdetail&sharetypeblogdetail&sharerId117376417&sharereferPC&sharesourceqxpapt&sharefromfrom_link. spring boot vue 搭建环境 一、浏览器二、jd…...
清华团队提出HistoCell,从组织学图像推断超分辨率细胞空间分布助力癌症研究|顶刊精析·25-03-02
小罗碎碎念 今天和大家分享一篇2025-02-21发表于nature communications的文章,内容涉及病理空转单细胞。 从组织学图像推断细胞空间分布对癌症研究意义重大,但现有方法存在标注工作量大、分辨率或特征挖掘不足等局限。研究旨在开发一种高效准确的方法。 …...
分布式锁—2.Redisson的可重入锁一
大纲 1.Redisson可重入锁RedissonLock概述 2.可重入锁源码之创建RedissonClient实例 3.可重入锁源码之lua脚本加锁逻辑 4.可重入锁源码之WatchDog维持加锁逻辑 5.可重入锁源码之可重入加锁逻辑 6.可重入锁源码之锁的互斥阻塞逻辑 7.可重入锁源码之释放锁逻辑 8.可重入锁…...
html+js 轮播图
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>轮播图示例</title><style>/* 基本样式…...
vue3:初学 vue-router 路由配置
承上一篇:nodejs:express js-mdict 作为后端,vue 3 vite 作为前端,在线查询英汉词典 安装 cnpm install vue-router -S 现在讲一讲 vue3:vue-router 路由配置 cd \js\mydict-web\src mkdir router cd router 我还…...
23种设计模式之《备忘录模式(Memento)》在c#中的应用及理解
程序设计中的主要设计模式通常分为三大类,共23种: 1. 创建型模式(Creational Patterns) 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。 工厂方法模式࿰…...
Python 爬取唐诗宋词三百首
你可以使用 requests 和 BeautifulSoup 来爬取《唐诗三百首》和《宋词三百首》的数据。以下是一个基本的 Python 爬虫示例,它从 中华诗词网 或类似的网站获取数据并保存为 JSON 文件。 import requests from bs4 import BeautifulSoup import json import time# 爬取…...
C语言408考研先行课第一课:数据类型
由于408要考数据结构……会有算法题…… 所以,需要C语言来进行一个预备…… 因为大一贪玩,C语言根本没学进去……谁能想到考研还用得到呢?【手动doge(bushi) 软件用的是Clion,可以自行搜索教程下载使用。…...
03 HarmonyOS Next仪表盘案例详解(二):进阶篇
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! 文章目录 前言1. 响应式设计1.1 屏幕适配1.2 弹性布局 2. 数据展示与交互2.1 数据卡片渲染2.2 图表区域 3. 事件处理机制3.1 点击事件处理3.2 手势…...
探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(一)
文章目录 2.3 Polar 编解码2.3.1 Polar 码简介与发展背景2.3.2 信道极化理论基础对称容量与巴氏参数对称容量 I ( W ) I(W) I(W)巴氏参数 Z ( W ) Z(W) Z(W)常见信道信道联合信道分裂信道极化 本博客为系列博客,主要讲解各基带算法的原理与应用,包括&…...
基础篇(一)强化学习是什么?从零开始理解智能体的学习过程
强化学习是什么?从零开始理解智能体的学习过程 你是否曾好奇过,人工智能是如何在复杂的环境中学会做出决策的?无论是打游戏的AI,还是自动驾驶的汽车,还是最近很火的DeepSeek它们的背后都离不开一种强大的技术——强化…...
如何直接导出某个conda环境中的包, 然后直接用 pip install -r requirements.txt 在新环境中安装
1. 导出 Conda 环境配置 conda list --export > conda_requirements.txt这将生成一个 conda_requirements.txt 文件,其中包含当前环境中所有包的列表及其版本信息。 2. 转换为 requirements.txt 文件 grep -v "^#" conda_requirements.txt | cut -d …...
基于 HTML、CSS 和 JavaScript 的智能九宫格图片分割系统
目录 1 前言 2 技术实现 2.1 HTML 结构 2.2 CSS 样式 2.3 JavaScript 交互 3 代码解析 3.1 HTML 部分 3.2 CSS 部分 3.3 JavaScript 部分 4 完整代码 5 运行结果 6 总结 6.1 系统特点 6.2 使用方法 1 前言 在当今数字化的时代,图片处理需求日益增长。…...
委托者模式(掌握设计模式的核心之一)
目录 问题: 举例: 总结:核心就是利用Java中的多态来完成注入。 问题: 今天刷面经,刷到装饰者模式,又进阶的发现委托者模式,发现还是不理解,特此记录。 举例: 老板…...
MySQL-高级查询
查询处理 排序(默认不是按主键排序的) order by 字段1[,字段2] [asc|desc] 默认是升序排序也可以指定 select 列表中列的序号进行排序如果是多个字段,那么在上一个字段排序完的基础上排序下一个 限制数量 limit 行数࿰…...
R JSON 文件
R JSON 文件 引言 在当今的数据分析和处理领域,R语言作为一种功能强大的统计计算和图形展示工具,被广泛应用于各种数据分析任务中。随着大数据时代的到来,数据的格式和结构变得越来越多样化。JSON(JavaScript Object Notation&a…...
Apache Kafka单节点极速部署指南:10分钟搭建开发单节点环境
Apache Kafka单节点极速部署指南:10分钟搭建开发单节点环境 Kafka简介: Apache Kafka是由LinkedIn开发并捐赠给Apache基金会的分布式流处理平台,现已成为实时数据管道和流应用领域的行业标准。它基于高吞吐、低延迟的设计理念,能够…...
Redis7——进阶篇(一)
前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三)Redis&#x…...
点云配准技术的演进与前沿探索:从传统算法到深度学习融合(4)
4、点云配准面临的挑战与应对策略 4.1 点云配准面临的主要挑战 在点云配准的实际应用中,尽管已经取得了显著的研究成果,但仍然面临着诸多复杂而严峻的挑战,这些挑战严重制约了点云配准技术在更多领域的广泛应用和深入发展。 在自动驾驶场景…...
