unis_sip/oms_web/docs/components/ListTable.md

8.5 KiB
Raw Blame History

ListTable 组件

组件说明

列表表格组件,基于 Ant Design Table 组件封装,提供统一的表格样式、行选择、分页、滚动和行点击等功能。

组件位置

src/components/ListTable/ListTable.jsx
src/components/ListTable/ListTable.css

参数说明

参数名 类型 必填 默认值 说明
columns Array - 表格列配置数组
dataSource Array - 表格数据源
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) 自定义渲染函数

默认分页配置

{
  pageSize: 10,
  showSizeChanger: true,
  showQuickJumper: true,
  showTotal: (total) => `共 ${total} 条`,
}

使用示例

基础用法

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}
    />
  )
}

带行选择

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>
  )
}

带行点击和高亮

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}
    />
  )
}

自定义分页

<ListTable
  columns={columns}
  dataSource={dataSource}
  pagination={{
    pageSize: 20,
    showSizeChanger: true,
    showQuickJumper: true,
    showTotal: (total) => `总计 ${total} 条记录`,
    pageSizeOptions: ['10', '20', '50', '100'],
  }}
/>

禁用分页

<ListTable
  columns={columns}
  dataSource={dataSource}
  pagination={false}
/>

带加载状态

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}
    />
  )
}

横向滚动(列较多时)

<ListTable
  columns={columns}
  dataSource={dataSource}
  scroll={{ x: 1600 }}  // 内容宽度超过容器时出现横向滚动
/>

固定列

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 }}
/>

完整示例

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 函数时,要注意性能,避免在渲染函数中进行复杂计算