nex_design/docs/components/ListTable.md

386 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# ListTable 组件
## 组件说明
列表表格组件,基于 Ant Design Table 组件封装,提供统一的表格样式、行选择、分页、滚动和行点击等功能。
## 组件位置
```
src/components/ListTable/ListTable.jsx
src/components/ListTable/ListTable.css
```
## 参数说明
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| columns | Array<ColumnConfig> | 是 | - | 表格列配置数组 |
| dataSource | Array<Object> | 是 | - | 表格数据源 |
| rowKey | string | 否 | 'id' | 行数据的唯一标识字段名 |
| selectedRowKeys | Array<string\|number> | 否 | [] | 选中行的 key 数组 |
| onSelectionChange | function(keys: Array) | 否 | - | 行选择变化回调 |
| pagination | Object\|false | 否 | 默认配置 | 分页配置false 表示不分页 |
| scroll | Object | 否 | { x: 1200 } | 表格滚动配置 |
| onRowClick | function(record: Object) | 否 | - | 行点击回调 |
| selectedRow | Object | 否 | - | 当前选中的行数据对象 |
| loading | boolean | 否 | false | 表格加载状态 |
| className | string | 否 | '' | 自定义类名 |
### ColumnConfig 列配置
继承自 Ant Design Table 的列配置,常用属性:
| 属性名 | 类型 | 说明 |
|--------|------|------|
| title | string\|ReactNode | 列标题 |
| dataIndex | string | 数据字段名 |
| key | string | 列唯一标识 |
| width | number | 列宽度 |
| align | 'left'\|'center'\|'right' | 对齐方式 |
| fixed | 'left'\|'right' | 固定列 |
| render | function(value, record, index) | 自定义渲染函数 |
### 默认分页配置
```javascript
{
pageSize: 10,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `共 ${total} 条`,
}
```
## 使用示例
### 基础用法
```jsx
import ListTable from '../components/ListTable/ListTable'
function MyPage() {
const columns = [
{
title: '序号',
dataIndex: 'id',
key: 'id',
width: 80,
align: 'center',
},
{
title: '用户名',
dataIndex: 'userName',
key: 'userName',
width: 150,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 120,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (status) => (
<Tag color={status === 'enabled' ? 'green' : 'default'}>
{status === 'enabled' ? '启用' : '停用'}
</Tag>
),
},
]
const dataSource = [
{ id: 1, userName: 'admin', name: '管理员', status: 'enabled' },
{ id: 2, userName: 'user', name: '张三', status: 'disabled' },
]
return (
<ListTable
columns={columns}
dataSource={dataSource}
/>
)
}
```
### 带行选择
```jsx
import { useState } from 'react'
import ListTable from '../components/ListTable/ListTable'
function UserListPage() {
const [selectedRowKeys, setSelectedRowKeys] = useState([])
return (
<div>
{/* 显示选中的数量 */}
<div>已选择 {selectedRowKeys.length} </div>
<ListTable
columns={columns}
dataSource={dataSource}
selectedRowKeys={selectedRowKeys}
onSelectionChange={setSelectedRowKeys}
/>
</div>
)
}
```
### 带行点击和高亮
```jsx
import { useState } from 'react'
import ListTable from '../components/ListTable/ListTable'
function UserListPage() {
const [selectedUser, setSelectedUser] = useState(null)
const handleRowClick = (record) => {
setSelectedUser(record)
// 打开详情抽屉等操作
setShowDetailDrawer(true)
}
return (
<ListTable
columns={columns}
dataSource={dataSource}
onRowClick={handleRowClick}
selectedRow={selectedUser}
/>
)
}
```
### 自定义分页
```jsx
<ListTable
columns={columns}
dataSource={dataSource}
pagination={{
pageSize: 20,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `总计 ${total} 条记录`,
pageSizeOptions: ['10', '20', '50', '100'],
}}
/>
```
### 禁用分页
```jsx
<ListTable
columns={columns}
dataSource={dataSource}
pagination={false}
/>
```
### 带加载状态
```jsx
import { useState, useEffect } from 'react'
function UserListPage() {
const [loading, setLoading] = useState(false)
const [dataSource, setDataSource] = useState([])
const fetchData = async () => {
setLoading(true)
try {
const data = await api.fetchUsers()
setDataSource(data)
} finally {
setLoading(false)
}
}
useEffect(() => {
fetchData()
}, [])
return (
<ListTable
columns={columns}
dataSource={dataSource}
loading={loading}
/>
)
}
```
### 横向滚动(列较多时)
```jsx
<ListTable
columns={columns}
dataSource={dataSource}
scroll={{ x: 1600 }} // 内容宽度超过容器时出现横向滚动
/>
```
### 固定列
```jsx
const columns = [
{
title: '序号',
dataIndex: 'id',
key: 'id',
width: 80,
fixed: 'left', // 固定在左侧
},
// ... 其他列
{
title: '操作',
key: 'action',
width: 200,
fixed: 'right', // 固定在右侧
render: (_, record) => (
<Space>
<Button type="link" size="small">编辑</Button>
<Button type="link" size="small" danger>删除</Button>
</Space>
),
},
]
<ListTable
columns={columns}
dataSource={dataSource}
scroll={{ x: 1600 }}
/>
```
### 完整示例
```jsx
import { useState } from 'react'
import ListTable from '../components/ListTable/ListTable'
import { Tag, Button, Space } from 'antd'
import { EditOutlined, DeleteOutlined } from '@ant-design/icons'
function UserListPage() {
const [selectedRowKeys, setSelectedRowKeys] = useState([])
const [selectedUser, setSelectedUser] = useState(null)
const [showDetailDrawer, setShowDetailDrawer] = useState(false)
const columns = [
{
title: '序号',
dataIndex: 'id',
key: 'id',
width: 80,
align: 'center',
},
{
title: '用户名',
dataIndex: 'userName',
key: 'userName',
width: 150,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 120,
},
{
title: '用户分组',
dataIndex: 'group',
key: 'group',
width: 150,
render: (text) => <Tag color="blue">{text}</Tag>,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
align: 'center',
render: (status) => (
<Tag color={status === 'enabled' ? 'green' : 'default'}>
{status === 'enabled' ? '启用' : '停用'}
</Tag>
),
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
render: (_, record) => (
<Space size="small" onClick={(e) => e.stopPropagation()}>
<Button
type="link"
size="small"
icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
编辑
</Button>
<Button
type="link"
size="small"
icon={<DeleteOutlined />}
danger
onClick={() => handleDelete(record)}
>
删除
</Button>
</Space>
),
},
]
const handleRowClick = (record) => {
setSelectedUser(record)
setShowDetailDrawer(true)
}
return (
<ListTable
columns={columns}
dataSource={filteredUsers}
selectedRowKeys={selectedRowKeys}
onSelectionChange={setSelectedRowKeys}
onRowClick={handleRowClick}
selectedRow={selectedUser}
scroll={{ x: 1400 }}
/>
)
}
```
## 样式定制
组件提供以下 CSS 类名供自定义样式:
- `.list-table-container` - 表格容器
- `.row-selected` - 选中行的类名
## 使用场景
1. **用户列表** - 显示和管理用户数据
2. **设备列表** - 显示和管理设备信息
3. **订单列表** - 显示订单数据
4. **任何需要表格展示的数据列表**
## 注意事项
1. `columns` 配置中的 `key` 必须唯一
2. `dataSource` 中的每条数据必须有 `rowKey` 指定的唯一标识字段(默认为 `id`
3. 操作列中的点击事件需要使用 `e.stopPropagation()` 阻止事件冒泡,避免触发行点击
4. 当列数较多时,建议设置合适的 `scroll.x` 值并固定首尾列
5. `selectedRow` 用于高亮显示,`selectedRowKeys` 用于多选
6. 分页的 `total` 值会自动根据 `dataSource.length` 计算
7. 使用 `render` 函数时,要注意性能,避免在渲染函数中进行复杂计算