-
Notifications
You must be signed in to change notification settings - Fork 284
feat: 新增虚拟滚动表格 #3346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat_v3.x
Are you sure you want to change the base?
feat: 新增虚拟滚动表格 #3346
Changes from all commits
acb0e5f
0619387
20e3830
0e47a9c
5292c85
4bb8e70
80d9a74
2810d64
c1778ec
25c4633
d32f67c
62b9d43
2116b98
83a111c
beba08e
1178a17
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
You are a Senior Front-End Developer and an Expert in ReactJS, NextJS, JavaScript, TypeScript, HTML, CSS and modern UI/UX frameworks (e.g., TailwindCSS, Shadcn, Radix). You are thoughtful, give nuanced answers, and are brilliant at reasoning. You carefully provide accurate, factual, thoughtful answers, and are a genius at reasoning. | ||
|
||
- Follow the user’s requirements carefully & to the letter. | ||
- First think step-by-step - describe your plan for what to build in pseudocode, written out in great detail. | ||
- Confirm, then write code! | ||
- Always write correct, best practice, DRY principle (Dont Repeat Yourself), bug free, fully functional and working code also it should be aligned to listed rules down below at Code Implementation Guidelines . | ||
- Focus on easy and readability code, over being performant. | ||
- Fully implement all requested functionality. | ||
- Leave NO todo’s, placeholders or missing pieces. | ||
- Ensure code is complete! Verify thoroughly finalised. | ||
- Include all required imports, and ensure proper naming of key components. | ||
- Be concise Minimize any other prose. | ||
- If you think there might not be a correct answer, you say so. | ||
- If you do not know the answer, say so, instead of guessing. | ||
|
||
### Coding Environment | ||
|
||
The user asks questions about the following coding languages: | ||
|
||
- ReactJS | ||
- NextJS | ||
- JavaScript | ||
- TypeScript | ||
- TailwindCSS | ||
- HTML | ||
- CSS | ||
|
||
### Code Implementation Guidelines | ||
|
||
Follow these rules when you write code: | ||
|
||
- Use early returns whenever possible to make the code more readable. | ||
- Always use Tailwind classes for styling HTML elements; avoid using CSS or tags. | ||
- Use “class:” instead of the tertiary operator in class tags whenever possible. | ||
- Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown. | ||
- Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes. | ||
- Use consts instead of functions, for example, “const toggle = () =>”. Also, define a type if possible. | ||
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1 @@ | ||||||
[{"label":"一键安装环境","name":"Install","description":"专注于解决工作空间环境问题","prompt":"你是一位专门从事解决工作空间环境问题的全栈工程师和DevOps专家,你的主要任务是帮助用户诊断、修复和配置当前工作空间`/Users/jiangqi147/github/nutui-react`的开发环境。\n\n## 核心职责\n\n### 1. 环境检测与诊断\n- 自动扫描工作空间中的项目文件(package.json, requirements.txt, pom.xml, Gemfile, go.mod等)\n- 识别项目所需的运行环境和依赖\n- 检测当前系统已安装的环境版本\n- 分析环境配置冲突和兼容性问题\n\n### 2. 主流环境支持\n**Node.js生态系统:**\n- 检测和安装Node.js(如果用户没要求推荐LTS版本)\n- 配置npm/yarn/pnpm包管理器\n- 处理node_modules依赖问题\n- 解决版本冲突和权限问题\n\n**Python生态系统:**\n- 安装Python(2.x/3.x版本管理)\n- 配置pip包管理器和虚拟环境(venv/conda)\n- 处理requirements.txt依赖安装\n- 解决Python路径和模块导入问题\n\n**Java生态系统:**\n- 安装和配置JDK/JRE(版本选择和JAVA_HOME设置)\n- 配置Maven/Gradle构建工具\n- 处理依赖下载和仓库配置\n- 解决类路径和编译问题\n\n**其他主流环境:**\n- Go语言环境配置\n- Ruby和Rails环境\n- PHP和Composer\n- .NET Core环境\n- Docker容器化环境\n\n### 3. 项目启动与运行\n- 分析项目启动脚本和配置文件\n- 提供标准化的启动命令\n- 配置开发服务器和热重载\n- 设置环境变量和配置文件\n- 处理端口冲突和服务依赖\n\n### 4. 问题解决策略\n- 提供跨平台解决方案(Windows/macOS/Linux)\n- 给出详细的安装步骤和命令\n- 提供多种安装方式选择(官方安装器/包管理器/容器化)\n- 预防常见错误和最佳实践建议\n- 提供环境验证和测试方法\n\n### 5. 交互方式\n- 首先询问用户的操作系统和项目类型\n- 逐步引导用户完成环境配置\n- 提供可复制的命令和脚本\n- 在每个步骤后确认执行结果\n- 遇到问题时提供多种备选方案\n\n## 工作流程\n1. **环境扫描**:分析工作空间文件结构,识别项目类型\n2. **需求评估**:确定所需的运行环境和版本要求\n3. **现状检查**:检测当前已安装的环境和工具\n4. **差距分析**:对比需求与现状,列出缺失项\n5. **安装指导**:提供详细的安装和配置步骤\n6. **验证测试**:确保环境配置正确可用\n7. **项目启动**:协助用户成功启动项目\n\n请始终保持耐心和专业,用通俗易懂的语言解释技术概念,并在每个关键步骤提供清晰的指导。现在请开始分析当前工作空间的环境需求。\n"}] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 硬编码本地绝对路径不可移植,且可能泄露开发者用户名
- "…配置当前工作空间`/Users/jiangqi147/github/nutui-react`的开发环境。"
+ "…配置当前工作空间`${WORKSPACE_ROOT}`的开发环境。" 同时在执行时由宿主侧将 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React, { useState } from 'react' | ||
import TableVirtual, { TableColumnProps } from '../../index.virtual' | ||
|
||
// 定义数据项接口 | ||
interface DataItem { | ||
name: string | ||
record: string | ||
age: number | ||
description?: string // 添加描述字段,用于测试不同高度的行 | ||
} | ||
|
||
const DemoNoVirtual = () => { | ||
// 生成大量数据 | ||
const generateData = (count: number): DataItem[] => { | ||
const data: DataItem[] = [] | ||
for (let i = 0; i < count; i++) { | ||
// 为部分行添加不同长度的描述,以测试动态高度 | ||
let description | ||
if (i % 3 === 0) { | ||
description = `这是一段较长的描述文本,用于测试动态高度。行号: ${i}. 这段文字会导致行高增加。` | ||
} else if (i % 5 === 0) { | ||
description = `这是一段非常非常长的描述文本,它会占用多行空间。这是为了测试虚拟滚动表格在处理不同高度的行时的表现。行号: ${i}. 我们希望表格能够正确计算每行的实际高度,并且在滚动时保持良好的性能和用户体验。` | ||
} else { | ||
description = undefined | ||
} | ||
|
||
data.push({ | ||
name: `Name ${i}`, | ||
record: ['小学', '初中', '高中', '大专', '本科'][i % 5], | ||
age: Math.floor(Math.random() * 50) + 10, | ||
description, | ||
}) | ||
} | ||
return data | ||
} | ||
|
||
// 定义列配置 | ||
const [columns] = useState<TableColumnProps[]>([ | ||
{ | ||
title: 'ID', | ||
key: 'id', | ||
width: 50, | ||
fixed: 'left', | ||
render: (_record: any, index: number) => { | ||
return index + 1 | ||
}, | ||
}, | ||
{ | ||
title: '姓名', | ||
key: 'name', | ||
width: 80, | ||
}, | ||
{ | ||
title: '学历', | ||
key: 'record', | ||
width: 60, | ||
}, | ||
{ | ||
title: '年龄', | ||
key: 'age', | ||
width: 70, | ||
sorter: (a: DataItem, b: DataItem) => a.age - b.age, | ||
}, | ||
{ | ||
title: '描述', | ||
key: 'description', | ||
width: 100, | ||
fixed: 'right', | ||
render: (record: DataItem) => { | ||
return record.description ? ( | ||
<div | ||
style={{ | ||
padding: '5px 0', | ||
lineHeight: '1.5', | ||
whiteSpace: 'normal', | ||
wordBreak: 'break-word', | ||
}} | ||
> | ||
{record.description} | ||
</div> | ||
) : ( | ||
'-' | ||
) | ||
}, | ||
}, | ||
]) | ||
|
||
// 使用状态管理数据 | ||
const [data] = useState(generateData(10)) | ||
|
||
return <TableVirtual columns={columns} data={data} height={400} bordered /> | ||
} | ||
|
||
export default DemoNoVirtual |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import React, { useState, useRef } from 'react' | ||
import TableVirtual, { | ||
TableColumnProps, | ||
VirtualTableRef, | ||
} from '../../index.virtual' | ||
|
||
// 定义数据项接口 | ||
interface DataItem { | ||
name: string | ||
record: string | ||
age: number | ||
description?: string // 添加描述字段,用于测试不同高度的行 | ||
} | ||
|
||
const DemoVirtual = () => { | ||
// 创建表格引用 | ||
const tableRef = useRef<VirtualTableRef>(null) | ||
|
||
Comment on lines
+15
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ref 未绑定导致示例中 scrollToIndex 无法使用 已创建 应用以下 diff 修复: - const tableRef = useRef<VirtualTableRef>(null)
+ const tableRef = useRef<VirtualTableRef>(null)
@@
- <TableVirtual
+ <TableVirtual
+ ref={tableRef}
columns={columns}
data={data}
virtual
height={400}
rowHeight={40} // 默认行高,实际会根据内容动态调整
overscan={10}
bordered
dynamicHeight // 启用动态高度
/> Also applies to: 109-119 🤖 Prompt for AI Agents
|
||
// 生成大量数据 | ||
const generateData = (count: number): DataItem[] => { | ||
const data: DataItem[] = [] | ||
for (let i = 0; i < count; i++) { | ||
// 为部分行添加不同长度的描述,以测试动态高度 | ||
let description | ||
if (i % 3 === 0) { | ||
description = `这是一段较长的描述文本,用于测试动态高度。行号: ${i}. 这段文字会导致行高增加。` | ||
} else if (i % 5 === 0) { | ||
description = `这是一段非常非常长的描述文本,它会占用多行空间。这是为了测试虚拟滚动表格在处理不同高度的行时的表现。行号: ${i}. 我们希望表格能够正确计算每行的实际高度,并且在滚动时保持良好的性能和用户体验。` | ||
} else { | ||
description = undefined | ||
} | ||
|
||
data.push({ | ||
name: `Name ${i}`, | ||
record: ['小学', '初中', '高中', '大专', '本科'][i % 5], | ||
age: Math.floor(Math.random() * 50) + 10, | ||
description, | ||
}) | ||
} | ||
return data | ||
} | ||
|
||
// 定义列配置 | ||
const [columns] = useState<TableColumnProps[]>([ | ||
{ | ||
title: 'ID', | ||
key: 'id', | ||
width: 50, | ||
fixed: 'left', | ||
render: (_record: any, index: number) => { | ||
return index + 1 | ||
}, | ||
}, | ||
{ | ||
title: '姓名', | ||
key: 'name', | ||
width: 80, | ||
}, | ||
{ | ||
title: '学历', | ||
key: 'record', | ||
width: 60, | ||
}, | ||
{ | ||
title: '年龄', | ||
key: 'age', | ||
width: 70, | ||
sorter: (a: DataItem, b: DataItem) => a.age - b.age, | ||
}, | ||
{ | ||
title: '描述', | ||
key: 'description', | ||
width: 100, | ||
fixed: 'right', | ||
render: (record: DataItem) => { | ||
return record.description ? ( | ||
<div | ||
style={{ | ||
padding: '5px 0', | ||
lineHeight: '1.5', | ||
whiteSpace: 'normal', | ||
wordBreak: 'break-word', | ||
}} | ||
> | ||
{record.description} | ||
</div> | ||
) : ( | ||
'-' | ||
) | ||
}, | ||
}, | ||
]) | ||
|
||
// 使用状态管理数据 | ||
const [data, setData] = useState(generateData(1000)) | ||
|
||
// 更新数据的方法 | ||
const updateData = (count: number) => { | ||
setData(generateData(count)) | ||
} | ||
|
||
// 滚动到指定行的方法 | ||
const handleScrollToRow = (index: number) => { | ||
if (tableRef.current) { | ||
tableRef.current.scrollToIndex(index) | ||
} | ||
} | ||
|
||
return ( | ||
<TableVirtual | ||
columns={columns} | ||
data={data} | ||
virtual | ||
height={400} | ||
rowHeight={40} // 默认行高,实际会根据内容动态调整 | ||
overscan={10} | ||
bordered | ||
dynamicHeight // 启用动态高度 | ||
/> | ||
) | ||
} | ||
|
||
export default DemoVirtual |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { Table, TableColumnProps } from '@nutui/nutui-react' | ||
import React, { useState } from 'react' | ||
|
||
const Demo15 = () => { | ||
const [data] = useState([ | ||
{ | ||
name: 'Tom', | ||
gender: '男', | ||
record: '小学', | ||
birthday: '2010-01-01', | ||
age: 10, | ||
}, | ||
{ | ||
name: 'Lucy', | ||
gender: '女', | ||
record: '本科', | ||
birthday: '2000-01-01', | ||
age: 30, | ||
}, | ||
{ | ||
name: 'Jack', | ||
gender: '男', | ||
record: '高中', | ||
birthday: '2020-01-01', | ||
age: 4, | ||
}, | ||
{ | ||
name: 'Sara', | ||
gender: '女', | ||
record: '高中', | ||
birthday: '2020-01-01', | ||
age: 6, | ||
}, | ||
{ | ||
name: 'Frank', | ||
gender: '男', | ||
record: '幼儿园', | ||
birthday: '2020-01-01', | ||
age: 3, | ||
}, | ||
]) | ||
|
||
const [columnsStickHeaderLeft] = useState<Array<TableColumnProps>>([ | ||
{ | ||
title: '姓名', | ||
key: 'name', | ||
align: 'center', | ||
fixed: 'left', | ||
width: 100, | ||
}, | ||
{ | ||
title: '性别', | ||
key: 'gender', | ||
}, | ||
{ | ||
title: '学历', | ||
key: 'record', | ||
}, | ||
{ | ||
title: '生日', | ||
key: 'birthday', | ||
}, | ||
{ | ||
title: '年龄', | ||
key: 'age', | ||
}, | ||
]) | ||
|
||
return ( | ||
<Table | ||
columns={columnsStickHeaderLeft} | ||
data={data} | ||
style={{ height: 150 }} | ||
/> | ||
) | ||
} | ||
export default Demo15 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
与本项目技术栈不符:Svelte 指令与 Tailwind-only 约束会误导 React/NutUI 贡献者
建议将规则改为 React/NutUI 友好版,并放宽 Tailwind-only 约束(可选用 clsx/twMerge 统一 className)。示例修订:
如需,我可以提交一版与 NutUI 风格系统对齐的完整规则重写。
📝 Committable suggestion
🧰 Tools
🪛 LanguageTool
[grammar] ~36-~36: There might be a mistake here.
Context: ... and on:keydown, and similar attributes. - Use consts instead of functions, for exa...
(QB_NEW_EN)
🤖 Prompt for AI Agents