移动端 h5-table react版本支持虚拟列表
介绍
适用于 react + ts 的 h5 移动端项目 table 组件
github 链接 :https://github.com/duKD/react-h5-table
有帮助的话 给个小星星
有两种表格组件
常规的:
支持 左侧固定 滑动 每行点击回调 支持 指定列排序 支持滚动加载更多
效果和之前写的vue3 版本类似
vue3 h5 表格

大数据量时 使用虚拟列表:
也支持 左侧固定 滑动 每行点击回调 支持 指定列排序 不支持滚动加载

开始
npm i @lqcoder/react-h5-table
入口 引入table样式文件
import "@lqcoder/react-h5-table/scripts/style.css";
常规版使用
相关 props 配置 说明
export type tablePropsType<T = any> = {rowKey?: string; //表格行 key 的取值字段 默认取id字段minTableHeight?: number; //表格最小高度showRowNum?: number; // 表格显示几行headerHeight?: number; // 头部默认高度rowHeight?: number; //每行数据的默认高度column: Array<columnItemType<T>>;tableData: Array<T>;clickOptions?: clickOptions<T>; // 是否需要处理点击事件disable?: boolean; // 是否启用下拉加载pullDownProps?: pullDownPropsType;changePullDownProps?: (args: pullDownPropsType) => void; // 修改加载状态handleHeadSortClick?: (propsKey: string, type: sortStatusType) => void;onload?: () => void; // 数据加载rootValue?: number; //
};export type columnItemType<T = any> = {title: string; // 列名dataIndex: string; // table data key 值width: number; // 列 宽度sortable?: boolean; //是否 支持排序align?: "left" | "center" | "right"; // 布局render?: (item: T, index?: number) => any; //自定义单元格显示的内容
};// 下拉加载相关配置
export type pullDownPropsType = {error?: boolean; // 数据加载失败loading?: boolean; // 数据处于加载状态finish?: boolean; // 数据 是否完全加载loadingText?: string; // 加载文案errorText?: string; // 失败文案finishedText?: string; // 完成文案offset?: number; //触发加载的底部距离
};// 点击相关配置
export type clickOptions<T> = {clickRender: (item: T, index: number) => React.JSX.Element; // 点击列触发渲染clickHeight: number; // 显示栏的高度
};
代码示例:
// App.tsx 文件
import { useRef, useState } from "react";
import {H5Table,clickOptions,columnItemType,sortStatusType,
} from "@lqcoder/react-h5-table";import Styles from "./App.module.scss";function App() {type dataType = {id: number;type?: number;select: string;position: string;use: string;markValue: string;cur: string;cost: string;newPrice: number;float: string;profit: string;count: string;};const column: Array<columnItemType<dataType>> = [{title: "班费/总值",width: 250,dataIndex: "rateAndSum",render(item, _index) {return (<section className="nameAndMarkValue"><div className="name">{item.select}<span className="type">{item.type === 1 ? "深" : "沪"}</span></div><div className="markValue">{item.markValue}=={item.id}</div></section>);},align: "left",},{title: "持仓/可用",dataIndex: "positionAndUse",sortable: true,width: 200,align: "right",render(item, _index) {return (<section className="positionAndUse"><div className="position">{item.position}</div><div className="use">{item.use}</div></section>);},},{title: "现价/成本",dataIndex: "curAndCost",sortable: true,width: 200,align: "right",render(item) {return (<section className="curAndCost"><div className="cur">{item.cur}</div><div className="cost">{item.cost}</div></section>);},},{title: "浮动/盈亏",dataIndex: "float",width: 200,align: "right",render(item) {return (<section className="floatAndProfit"><div className="float">{item.float}</div><div className="profit">{item.profit}</div></section>);},},{title: "账户资产",dataIndex: "count",width: 200,},];const temp = Array.from({ length: 20 }).map((item, index) => {return {id: index,select: "三年二班",type: 1,position: `${27000 + index * 10}`,use: "5,000",markValue: "500,033.341",cur: "30.004",cost: "32.453",newPrice: 20,float: "+18,879.09",profit: "-5.45%",count: "120,121",};});const dataRef = useRef(temp);const [data, setData] = useState(temp);const [pullDownProps, setPullDownProps] = useState({offset: 10,error: false, // 数据加载失败loading: false, // 数据处于加载状态finish: false, // 数据 是否完全加载loadingText: "加载中...", // 加载文案errorText: "出错了", // 失败文案finishedText: "到底了", // 完成文案});const onload = () => {setTimeout(() => {const len = data.length;setData(data.concat(Array.from({ length: 10 }).map((item, index) => {return {id: len + index,select: "三年二班",type: 1,position: "28000",use: "5,000",markValue: "500,033.341",cur: "30.004",cost: "32.453",newPrice: 20,float: "+18,879.09",profit: "-5.45%",count: "120,121",};})));dataRef.current = dataRef.current.concat(Array.from({ length: 10 }).map((item, index) => {return {id: len + index,select: "三年二班",type: 1,position: "28000",use: "5,000",markValue: "500,033.341",cur: "30.004",cost: "32.453",newPrice: 20,float: "+18,879.09",profit: "-5.45%",count: "120,121",};}));setPullDownProps({...pullDownProps,loading: false,});}, 1000);};const changePullDownProps = (args: any) => {setPullDownProps(args);};/*** 处理排序按钮回调 处理逻辑交给开发* @param propsKey 点击的列名* @param type 0 默认 1 升 2 降* @returns*/const handleHeadSortClick = (propsKey: string, type: sortStatusType) => {if (type === 0) {setData(dataRef.current);return;}if (propsKey === "positionAndUse") {if (type === 1) {const temp = [...dataRef.current].sort((a, b) => Number(b.position) - Number(a.position));setData(temp);} else {const temp = [...dataRef.current].sort((a, b) => Number(a.position) - Number(b.position));setData(temp);}}if (propsKey === "curAndCost") {if (type === 1) {const temp = [...dataRef.current].sort((a, b) => Number(b.cur) - Number(a.cur));setData(temp);} else {const temp = [...dataRef.current].sort((a, b) => Number(a.cur) - Number(b.cur));setData(temp);}}};const handelSell = () => {console.log("handelSell----");};const clickOptions: clickOptions<dataType> = {clickRender(item, index) {return (<section className={Styles["rowDownMark"]}><div className={Styles["rowDownMark-item"]} onClick={handelSell}>买入</div><div className={Styles["rowDownMark-item"]}>卖出</div><div className={Styles["rowDownMark-item"]}>行情</div></section>);},clickHeight: 60,};return (<><H5Table<dataType>disablecolumn={column}tableData={data}onload={onload}pullDownProps={pullDownProps}changePullDownProps={changePullDownProps}handleHeadSortClick={handleHeadSortClick}clickOptions={clickOptions}></H5Table></>);
}export default App;
// App.module.scss
.app {color: red;font-size: 20px;.container {color: aqua;}
}
.rowDownMark {width: 100%;display: flex;height: 60px;background-color: #fcfcfc;align-items: center;
}
.rowDownMark-item {flex-grow: 1;color: #309fea;text-align: center;
}
大数据量时 使用虚拟列表
相关props 说明
export type virtualTablePropsType<T = any> = {rowKey?: string; //表格行 key 的取值字段 默认取id字段minTableHeight?: number; //表格最小高度showRowNum?: number; // 表格显示几行headerHeight?: number; // 头部默认高度rowHeight?: number; //每行数据的默认高度column: Array<columnItemType<T>>;tableData: Array<T>;clickOptions?: clickOptions<T>; // 是否需要处理点击事件handleHeadSortClick?: (propsKey: string, type: sortStatusType) => void;rootValue?: number; //
};// 0 默认 1 升 2 降
export type sortStatusType = 0 | 1 | 2;export interface virtualTableInstance {scrollIntoView: (index: number) => void;
}export type columnItemType<T = any> = {title: string; // 列名dataIndex: string; // table data key 值width: number; // 列 宽度sortable?: boolean; //是否 支持排序align?: "left" | "center" | "right"; // 布局render?: (item: T, index?: number) => any; //自定义单元格显示的内容
};// 点击相关配置
export type clickOptions<T> = {clickRender: (item: T, index: number) => React.JSX.Element; // 点击列触发渲染clickHeight: number; // 显示栏的高度
};
代码示例:
// App.tsx
import { useRef, useState } from "react";
import {H5VirtualTable,clickOptions,columnItemType,sortStatusType,virtualTableInstance,
} from "@lqcoder/react-h5-table";import Styles from "./App.module.scss";function App() {type dataType = {id: number;type?: number;select: string;position: string;use: string;markValue: string;cur: string;cost: string;newPrice: number;float: string;profit: string;count: string;};const column: Array<columnItemType<dataType>> = [{title: "班费/总值",width: 250,dataIndex: "rateAndSum",render(item, _index) {return (<section className="nameAndMarkValue"><div className="name">{item.select}<span className="type">{item.type === 1 ? "深" : "沪"}</span></div><div className="markValue">{item.markValue}=={item.id}</div></section>);},align: "left",},{title: "持仓/可用",dataIndex: "positionAndUse",sortable: true,width: 200,align: "right",render(item, _index) {return (<section className="positionAndUse"><div className="position">{item.position}</div><div className="use">{item.use}</div></section>);},},{title: "现价/成本",dataIndex: "curAndCost",sortable: true,width: 200,align: "right",render(item) {return (<section className="curAndCost"><div className="cur">{item.cur}</div><div className="cost">{item.cost}</div></section>);},},{title: "浮动/盈亏",dataIndex: "float",width: 200,align: "right",render(item) {return (<section className="floatAndProfit"><div className="float">{item.float}</div><div className="profit">{item.profit}</div></section>);},},{title: "账户资产",dataIndex: "count",width: 200,},];const temp = Array.from({ length: 20000 }).map((item, index) => {return {id: index,select: "三年二班",type: 1,position: `${27000 + index * 10}`,use: "5,000",markValue: "500,033.341",cur: "30.004",cost: "32.453",newPrice: 20,float: "+18,879.09",profit: "-5.45%",count: "120,121",};});const dataRef = useRef(temp);const tableRef = useRef<virtualTableInstance>();const [num, setNum] = useState(1);const [data, setData] = useState(temp);/*** 处理排序按钮回调 处理逻辑交给开发* @param propsKey 点击的列名* @param type 0 默认 1 升 2 降* @returns*/const handleHeadSortClick = (propsKey: string, type: sortStatusType) => {if (type === 0) {setData(dataRef.current);return;}if (propsKey === "positionAndUse") {if (type === 1) {const temp = [...dataRef.current].sort((a, b) => Number(b.position) - Number(a.position));setData(temp);} else {const temp = [...dataRef.current].sort((a, b) => Number(a.position) - Number(b.position));setData(temp);}}if (propsKey === "curAndCost") {if (type === 1) {const temp = [...dataRef.current].sort((a, b) => Number(b.cur) - Number(a.cur));setData(temp);} else {const temp = [...dataRef.current].sort((a, b) => Number(a.cur) - Number(b.cur));setData(temp);}}};const handelSell = () => {console.log("handelSell----");};const clickOptions: clickOptions<dataType> = {clickRender(item, index) {return (<section className={Styles["rowDownMark"]}><div className={Styles["rowDownMark-item"]} onClick={handelSell}>买入</div><div className={Styles["rowDownMark-item"]}>卖出</div><div className={Styles["rowDownMark-item"]}>行情</div></section>);},clickHeight: 60,};const scrollTo = () => {tableRef.current?.scrollIntoView(num);};const getValue = (val: any) => {setNum(Number(val.target.value) || 0);};return (<><input type="text" onChange={getValue} /><button onClick={scrollTo}>跳到</button><H5VirtualTable<dataType>disablecolumn={column}tableData={data}handleHeadSortClick={handleHeadSortClick}clickOptions={clickOptions}ref={tableRef}></H5VirtualTable></>);
}export default App;
// App.module.scss
.app {color: red;font-size: 20px;.container {color: aqua;}
}
.rowDownMark {width: 100%;display: flex;height: 60px;background-color: #fcfcfc;align-items: center;
}
.rowDownMark-item {flex-grow: 1;color: #309fea;text-align: center;
}
相关文章:
移动端 h5-table react版本支持虚拟列表
介绍 适用于 react ts 的 h5 移动端项目 table 组件 github 链接 :https://github.com/duKD/react-h5-table 有帮助的话 给个小星星 有两种表格组件 常规的: 支持 左侧固定 滑动 每行点击回调 支持 指定列排序 支持滚动加载更多 效果和之前写的vue…...
解决Windows系统本地端口被占用的问题
一、解决Windows系统本地端口被占用的问题,首先我们要在虚拟机上人为的占用本地端口 二、占用端口方法:以管理员身份运行cmd;输入net stop http;如果提示是否真的需要停止这些服务,则选择“Y”;完成后输入:sc config http startdisabled 弹出上图内容则成…...
(超全七大错误)Invalid bound statement (not found): com.xxx.dao.xxxDao.add
1.确保你把dao和mapper都在applicationContext.xml中都扫描了 xml文件 <bean id"sqlSessionFactory" class"org.mybatis.spring.SqlSessionFactoryBean"><property name"dataSource" ref"dataSource"/><property nam…...
【操作系统】实验八 proc文件系统
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…...
基于RMF的信贷风控标签客户分层管理
根据美国 数据库营销研究所Arthur Hughes的研究,客户数据库中有3个神奇的要素,这3个要素构成了数据分析最好的指标:最近一次消费 (Recency)、消费频率(Frequency)、消费金额 (Monetary)。这就是RMF模型,RMF模型是用户分层的重要手…...
【MySQL】如何通过DDL去创建和修改员工信息表
🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-fmKISDBsFq74ab2Z {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…...
Spring 事务原理一
从本篇博客开始,我们将梳理Spring事务相关的知识点。在开始前,想先给自己定一个目标:通过此次梳理要完全理解事务的基本概念及Spring实现事务的基本原理。为实现这个目标我想按以下几个步骤进行: 讲解事务中的一些基本概念使用Sp…...
creo草绘3个实例学习笔记
creo草绘3个实例 文章目录 creo草绘3个实例草绘01草绘02草绘03 草绘01 草绘02 草绘03...
Modern C++ std::move的实现原理
前言 有一节我们分析了std::bind的实现原理,本节稍作休息分析一个比较简单的std::move 原理 std::move的原理太简单了,一句话:就是把传进来的参数强转为右值引用类型。作用为调用移动构造函数,或移动赋值函数。下面通过例子和代…...
爬虫工作量由小到大的思维转变---<第四十章 Scrapy Redis 实现IP代理池管理的最佳实践>
前言: 本篇是要结合上篇一起看的姊妹篇:爬虫工作量由小到大的思维转变---<第三十九章 Scrapy-redis 常用的那个RetryMiddleware>-CSDN博客 IP代理池的管理对于确保爬虫的稳定性和数据抓取的匿名性至关重要。围绕Scrapy-Redis框架和一个具体的IP代理池中…...
C# 实现 XOR 密码
XOR密码(异或密码)是一种简单的加密算法,它使用异或(XOR)操作来对明文和密钥进行加密和解密。 异或操作是一种位运算,它对两个二进制数的对应位进行比较,如果两个位相同(都为0或都为…...
【Web前端开发基础】CSS3之空间转换和动画
CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换:translate3d(位移)1.4 3D转换:perspective(视角)1.5 3D转换:rotate3d(旋转&a…...
Go实现一个简单的烟花秀效果(附带源码)
在 Go 语言中,要实现烟花秀效果可以使用 github.com/fogleman/gg 包进行绘图。以下是一个简单的例子: 首先,确保你已经安装了(有时候需要梯子才可以安装) github.com/fogleman/gg 包: go get -u github.c…...
【数学建模】插值与拟合
文章目录 插值插值方法用Python解决插值问题 拟合最小二乘拟合数据拟合的Python实现 适用情况 处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式时,构造一个简单函数作为要考察数据或复杂函数的近似 定义 给定一组数据,需要确定满…...
全卷积网络:革新图像分析
一、介绍 全卷积网络(FCN)的出现标志着计算机视觉领域的一个重要里程碑,特别是在涉及图像分析的任务中。本文深入探讨了 FCN 的概念、它们的架构、它们与传统卷积神经网络 (CNN) 的区别以及它们在各个领域的应用。 就像…...
ubuntu20.04 格式化 硬盘 扩展硬盘GParted
如何在 Ubuntu 22.04 LTS 上安装分区编辑器 GParted?_gparted安装-CSDN博客 sudo apt install gparted 步骤5:启动GParted 安装完成后,您可以在应用程序菜单中找到GParted。点击它以启动分区编辑器。 通过以上步骤,您可以在Ubun…...
docker的资源限制(cgroup)
前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…...
ChatGPT与文心一言:应用示例与体验比较
ChatGPT 和文心一言哪个更好用? 为了更好地感受ChatGPT和文心一言这两款AI助手如何在实际运用中竞相辉映,我将提供一些典型的应用示例。这些示例都取自真实的用户体验,以帮助解释这两种工具如何让日常生活或工作变得更加轻松。 ChatGPT Ch…...
紫光展锐T760_芯片性能介绍_展锐T760安卓核心板定制
展锐T760核心板是一款基于国产5G芯片的智能模块,采用紫光展锐T760制程工艺为台积电6nm工艺,支持工艺具有出色的能效表现。其采用主流的44架构的八核设计,包括4颗2.2GHz A76核心和4颗A55核心设计,内存单元板载可达8GB Ram256GB ROM…...
从动力系统研究看当今数学界
6.3... Milnor’s definition of “attractors” which has been criticized above by us). The work of [KSS2] of asserting the existence of “nice open set” of Ω(p.148) would be likely not verified, for example we think the first sentence “… since f is nont…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
