antd 高级组件 ProComponents 之 高级表格 ProTable

  1. 一般后台管理系统,大部分页面功能都是列表和表单的形式。即便使用了组件<Table />、<Form />等,依旧需要写大量高度重复性的代码,比如列表页通常会有筛选栏、操作栏、表格区域、和分页栏四个部分,新增/编辑页通常有N+表单项(eg: 输入框、下拉框、级联框、单选按钮、多选按钮等等)。之前也考虑将高重复性的代码抽离成组件,通过配置参数,来实现相对应的功能。在组件设计阶段,将组件的灵活性和易用性作为首要目标(当然终极目标肯定是要实现基础功能,不然做组件的意义何在),因此将每一个模块作为单独的组件,最终实现了筛选栏、操作栏、表单项三个组件,后来随着业务需求的增加,也在不断扩展组件的能力,目前相对比较成熟,可以满足基础的列表/表单页面功能。
  2. 最近在做 react 项目,发现 antd 的 ProComponents 挺有意思的,ProComponents 提供了更高程度的抽象,很适合于不需要过多设计的中后台类应用,ProComponents 的设计思路是「一个状态加一系列行为」「一个组件≈一个页面」。
    1. 一个状态加一系列行为:开发者只需要定义一个状态,重型组件会自动生成一系列行为。以 table 为例,需要有一个状态 dataSource 来存储请求的数据,为了更好的体验,还需要一个 loading,这样最基础的功能就有一系列的行为,需要先设置 loading=true,然后发送请求,请求完成后设置 dataSourceloading=false,再加上分页、搜索等功能,行为就更加繁杂,而这系列行为绝大部分属于重复性工作。我们来看一下 ProTable 对此做了什么工作,ProTable 通过抽象出一个 request 的 API,将 dataSource 和 loading 等状态以及其行为进行封装,这种封装模式可以让前端减少重复性工作,专注于业务开发。
    2. 一个组件≈一个页面:重型组件的思想是提供页面级别的抽象。还是以 table 为例,一个列表页,需要有筛选相关的表单组件、表格组件、加载中组件等等。而 ProTable 一个组件满足以上所有功能,支持接口请求和自动生成筛选表单。
  3. 不过使用 ProComponents 的前提是,没有个性化特别强的需求,虽然说 ProTable 支持完全降级为 table 使用,但会有一种“杀鸡用牛刀”的感觉,而且还很增加开发人员的理解成本,没有必要。

ProTable

1. 常用API

(1)request:ProTable 最重要的 API,request 会接收一个对象。对象中必须要有 data 和 success,如果需要手动分页 total 也是必需的。request 会接管 loading 的设置,同时在查询表单查询和 params 参数发生修改时重新执行。同时 查询表单的值和 params 参数也会带入。

(2)columns:表格列的配置描述。

(3)toolBarRender:渲染工具栏,支持返回一个 dom 数组,会自动增加 margin-right

(4)search:是否显示搜索表单,传入对象时为搜索表单的配置。

(5)actionRef:Table action 的引用,便于自定义触发。

(6)formRef:可以获取到查询表单的 form 实例,用于一些灵活的配置。

(7)rowKey:表格行 key 的取值,可以是字符串或一个函数。

(8)scroll:表格是否可滚动,也可以指定滚动区域的宽、高,参考 配置项 文档。

(9)pagination:分页器,设为 false 时不展示和进行分页,参考 配置项 或 pagination 文档。

(10)options:table 工具栏,设为 false 时不显示,传入 function 会点击时触发({{ density?: boolean, fullScreen: boolean | function, reload: boolean | function, setting: boolean | SettingOptionType }})。

(11)editable:可编辑表格的相关配置。

示例:

<ProTable
  columns={columns}
  actionRef={actionRef}
  options={false}
  request={async (params: any = {}, sort, filter) => {
    const data = {
      ...params,
      page: params.current,
      per_page: params.pageSize
    };
    const res: any = await companyList(data);
    return {
      data: res.data.data,
      success: res?.code === 1,
      total: +res.data.total
    };
  }}
  rowKey="id"
  search={{
    labelWidth: 100,
    defaultCollapsed: false
  }}
  scroll={{ x: "100%", y: "calc(100vh - 300px)" }}
  pagination={{
    showSizeChanger: true
  }}
  toolBarRender={() => [
    <Search placeholder="请输入关键字"></Search>,
    <Button type="primary" onClick={handleExportAll}>
      导出全部
    </Button>
  ]}
/>;

2. Search 搜索表单配置

(1)labelWidth:标签的宽度,可以设置具体的数值,也可以设置为auto,根据标签字数进行调整。

(2)defaultCollapsed:默认是否收起。

(3)span:配置查询表单的列数,可以设置具体的数值,也可以设置为'ColConfig'类型(defaultColConfig = { xs:24, sm:24, md:12, lg:12, xl:8, xxl:6 })。

(4)optionRender:自定义操作栏。

(5)showHiddenNum:是否显示收起之后显示隐藏个数。

(6)filterType:过滤表单类型('query' | 'light'),默认使用'query'

3. Columns 列定义

(1)title:列头显示文字。

(2)dataIndex:列数据在数据项中对应的路径,支持通过数组查询嵌套路径。

(3)width:列宽度。

(4)fixed:列是否固定,可选 true (等效于 left) left right

(5)valueType:值的类型,会生成不同的渲染器。(后面详细说一下valueType

(6)valueEnum:值的枚举,支持传入一个 Object 或者是 Map,它会自动转化把值当成 key 来取出要显示的内容,可以配合 valueType 使用。

(7)order:查询表单中的权重,权重大排序靠前。

(8)search:配置列的搜索相关,false 为隐藏。

(9)editable:在编辑表格中是否可编辑的,函数的参数和 table 的 render 一样。

(10)hideInSearch:在查询表单中不展示此项。

(11)hideInTable:在 Table 中不展示此列。

(12)request:从服务器请求枚举。

(13)render:类似 table 的 render,第一个参数变成了 dom,增加了第四个参数 action。

示例:

const columns = [
  {
    title: "单位简称",
    dataIndex: "short_name",
    search: false,
    width: "100px"
  },
  {
    title: "是否名企",
    dataIndex: "famous",
    hideInTable: true,
    valueType: "select",
    valueEnum: {
      0: { text: "普通单位" },
      1: { text: "名企" }
    }
  },
  {
    title: "操作",
    width: "140px",
    fixed: "right",
    valueType: "option",
    render: (text: string, row: any) => (
      <Space>
        <Button
          type="link"
          size="small"
          onClick={() => history.push(`?id=${row.id}`)}
        >
          编辑
        </Button>
        <Button type="link" size="small" onClick={() => setRemark(row)}>
          备注
        </Button>
      </Space>
    )
  }
];

4. valueType 列表

valueType 是 ProComponents 的灵魂,ProComponents 会根据 valueType 来映射成不同的表单项。

ProTable 封装了一些常用的值类型来减少重复的 render 操作,配置一个 valueType 即可展示格式化响应的数据。

ProTable 中常用的:

(1)date:日期。

(2)dateTime:日期时间。

(3)dateRange:日期区间。

(4)dateTimeRange:日期时间区间。

(5)text:文本框。

(6)select:下拉框。

(7)treeSelect:树形下拉框。

(8)cascader:级联选择器。

valueType 也支持自定义,参考 demo

5. ListToolBarProps 配置

除了可以使用 toolBarRender 渲染工具栏,还可以使用 toolbar 灵活定义工具栏,包括标题、描述、搜索、操作、设置等配置。

6. editable 编辑行配置

(1)type:可编辑表格的类型,单行编辑或者多行编辑,single | multiple

(2)editableKeys:正在编辑的行,受控属性。 默认 key 会使用 rowKey 的配置,如果没有配置会使用 index,建议使用 rowKey。

(3)onChange:行数据被修改的时候触发。

(4)onSave:保存一行的时候触发。

(5)onDelete:删除一行的时候触发。

(6)onCancel:取消编辑一行时触发。

(7)actionRender:自定义编辑模式的操作栏,默认提供了三种操作:保存,删除 和 取消。

示例:

editable={{
  type: "multiple",
  actionRender: (row, config, defaultDom) => [
    defaultDom.save,
    defaultDom.cancel
  ]
  //onSave: (_, row: any) => editData(row)
}}

7. recordCreatorProps 新建行配置

(1)position:添加的位置,顶部添加还是末尾添加,top | bottom

(2)record:新增的记录,需要设置 rowKey,不写的话,会使用 index 当行 id。

(3)style:按钮的样式设置,可以设置按钮是否显示,这样可以做最大行限制和最小行限制之类的功能。

示例:

recordCreatorProps={{
  position: "top",
  record: () => ({ id: (Math.random() * 1000000).toFixed(0) })
}}

8. ActionRef 自定义触发(TODO:后面有时间再补充)

遇到的问题

1. 引入组件的时候按需引入即可,原因主要有两个:一个是整个包引入后体积比较大,一个是整包引入后有些地方的国际化会有点问题。

// 按需引入
"@ant-design/pro-card": "^1.20.11",
"@ant-design/pro-descriptions": "^1.11.7",
"@ant-design/pro-form": "^1.70.0",
 "@ant-design/pro-table": "2.77.0",

// 整包引入
"@ant-design/pro-components": "^1.1.7",

2. 在360等浏览器中打开,react 报错,解决方案如下:

// public/index.html
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />

// src/index.tsx
import "core-js/es";
import "react-app-polyfill/ie9";
import "react-app-polyfill/stable";

// package.json
{
    "dependencies": {
        "core-js": "^3.23.3",
        "react-app-polyfill": "^3.0.0",
    },
    "browserslist": {
        "production": [
            "not op_mini all",
              "ie > 9"
            ],
        "development": [
            "ie > 9"
        ]
    }
}

参考文档

  1. React+Antd兼容ie浏览器,360安全浏览器兼容模式
  2. ProTable
posted @ 2022-08-10 14:04  shellon  阅读(19013)  评论(0编辑  收藏  举报