Table 表格

展示行列数据。

何时使用

  • 当有大量结构化的数据需要展现时;
  • 当需要对数据进行排序、搜索、分页、自定义操作等复杂行为时。

注意事项

Pro Table 功能集成多,逻辑复杂,因此存在一定性能问题,在开发技术选型前一定要注意考量。

性能瓶颈

  • 多字段:单行字段 50+ (10条)影响首次渲染速度,影响不大
  • 大数据量: 单次渲染总单元格数超过 1000+

处理方案

根据具体场景及需求使用基础表格或大数据表格

相关教程:Table

代码演示

基础

最简单的表格示例。

Table表格 - 图1

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table } from 'choerodon-ui/pro';
  4. class App extends React.Component {
  5. userDs = new DataSet({
  6. primaryKey: 'userid',
  7. name: 'user',
  8. autoQuery: true,
  9. pageSize: 5,
  10. fields: [
  11. {
  12. name: 'userid',
  13. type: 'string',
  14. label: '编号',
  15. required: true,
  16. },
  17. {
  18. name: 'name',
  19. type: 'intl',
  20. label: '姓名',
  21. },
  22. {
  23. name: 'age',
  24. type: 'number',
  25. label: '年龄',
  26. max: 100,
  27. step: 1,
  28. },
  29. {
  30. name: 'sex',
  31. type: 'string',
  32. label: '性别',
  33. lookupCode: 'HR.EMPLOYEE_GENDER',
  34. required: true,
  35. },
  36. { name: 'enable', type: 'boolean', label: '是否开启' },
  37. ],
  38. });
  39. get columns() {
  40. return [
  41. { name: 'userid' },
  42. { name: 'name', editor: true },
  43. { name: 'age', editor: true },

级联

头行场景,级联列表。子表格依赖于头表格参数查询。使用 DataSet children 属性关联数据集。

Table表格 - 图2

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. TextField,
  7. Modal,
  8. Button,
  9. Lov,
  10. Tabs,
  11. } from 'choerodon-ui/pro';
  12. const { Column } = Table;
  13. const { TabPane } = Tabs;
  14. function editorRenderer(record) {
  15. return record.status === 'add' ? <TextField /> : null;
  16. }
  17. function maleFilter(record) {
  18. return record.get('sex') === 'M' || !record.get('sex');
  19. }
  20. // 过滤展示数据 结合 table filter
  21. function femaleFilter(record) {
  22. return record.get('sex') === 'F';
  23. }
  24. class App extends React.Component {
  25. friendsDs = new DataSet({
  26. dataToJSON: 'normal',
  27. queryUrl: '/dataset/user/queries',
  28. cascadeParams(parent) {
  29. console.log('cascadeParams', parent.toData());
  30. // 级联查询参数 (record, primaryKey) => object
  31. return {
  32. __parent: parent.toData(),
  33. };
  34. },
  35. fields: [
  36. { name: 'name', type: 'string', label: '姓名', required: true },
  37. { name: 'age', type: 'number', label: '年龄', step: 1 },
  38. {
  39. name: 'sex',
  40. type: 'string',
  41. label: '性别',
  42. lookupCode: 'HR.EMPLOYEE_GENDER',
  43. required: true,
  44. },
  45. ],
  46. events: {
  47. query: ({ params, data }) =>
  48. console.log('friend query parameter', params, data),
  49. },
  50. });
  51. enemyFriendsDs = new DataSet({
  52. dataToJSON: 'normal',
  53. selection: 'single',
  54. fields: [
  55. { name: 'name', type: 'string', label: '姓名', required: true },
  56. { name: 'age', type: 'number', label: '年龄', step: 1 },
  57. {

显示原始值

使用 pristine 属性控制修改后仍显示原始值。

Table表格 - 图3

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. Form,
  7. TextField,
  8. NumberField,
  9. SelectBox,
  10. Modal,
  11. Button,
  12. } from 'choerodon-ui/pro';
  13. const { Column } = Table;
  14. class EditButton extends React.Component {
  15. handleClick = e => {
  16. const { record, onClick } = this.props;
  17. onClick(record, e);
  18. };
  19. render() {
  20. return <Button funcType="flat" icon="mode_edit" onClick={this.handleClick} size="small" />;
  21. }
  22. }
  23. class App extends React.Component {
  24. userDs = new DataSet({
  25. primaryKey: 'userid',
  26. name: 'user',
  27. autoQuery: true,
  28. pageSize: 5,
  29. fields: [
  30. {
  31. name: 'userid',
  32. type: 'string',
  33. label: '编号',
  34. required: true,
  35. },
  36. {
  37. name: 'name',
  38. type: 'intl',
  39. label: '姓名',
  40. },
  41. {

行内编辑

editMode 为 inline 的单行编辑模式。

Table表格 - 图4

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button } from 'choerodon-ui/pro';
  4. const { Column } = Table;
  5. class App extends React.Component {
  6. ds = new DataSet({
  7. primaryKey: 'userid',
  8. name: 'user',
  9. autoQuery: true,
  10. pageSize: 5,
  11. cacheSelection: true,
  12. fields: [
  13. {
  14. name: 'userid',
  15. type: 'string',
  16. label: '编号',
  17. required: true,
  18. unique: true,
  19. help: '主键,区分用户',
  20. },
  21. { name: 'name', type: 'intl', label: '姓名' },
  22. {
  23. name: 'age',
  24. type: 'number',
  25. label: '年龄',
  26. unique: 'uniqueGroup',
  27. max: 100,
  28. step: 1,
  29. help: '用户年龄,可以排序',
  30. },
  31. {
  32. name: 'numberMultiple',
  33. type: 'number',
  34. label: '数值多值',
  35. multiple: true,
  36. min: 10,
  37. max: 100,
  38. step: 0.5,
  39. },
  40. { name: 'code', type: 'object', label: '代码描述', lovCode: 'LOV_CODE' },
  41. {
  42. name: 'code_code',
  43. bind: 'code.code',

自定义行内编辑

通过 editor 自定义控制行内编辑

Table表格 - 图5

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, Switch } from 'choerodon-ui/pro';
  4. const { Column } = Table;
  5. class App extends React.Component {
  6. userDs = new DataSet({
  7. primaryKey: 'userid',
  8. name: 'user',
  9. autoQuery: true,
  10. pageSize: 5,
  11. fields: [
  12. {
  13. name: 'userid',
  14. type: 'string',
  15. label: '编号',
  16. },
  17. {
  18. name: 'name',
  19. type: 'intl',
  20. label: '姓名',
  21. required: true,
  22. },
  23. {
  24. name: 'age',
  25. type: 'number',
  26. label: '年龄',
  27. max: 100,
  28. step: 1,
  29. },
  30. {
  31. name: 'sex',
  32. type: 'string',
  33. label: '性别',
  34. lookupCode: 'HR.EMPLOYEE_GENDER',
  35. required: true,
  36. },
  37. { name: 'enable', type: 'boolean', label: '是否开启' },
  38. ],
  39. events: {
  40. submit: ({ data }) => console.log('submit data', data),
  41. },
  42. });

树形数据

树形 Table 的功能展示。

Table表格 - 图6

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, Icon } from 'choerodon-ui/pro';
  4. import { observer } from 'mobx-react';
  5. const { Column } = Table;
  6. function iconRenderer({ record, text }) {
  7. return [
  8. <Icon key="icon" type={record.get('icon')} />,
  9. <span key="text">{text}</span>,
  10. ];
  11. }
  12. function expandedRowRenderer({ record }) {
  13. return (
  14. <p>
  15. 功能代码:{record.get('functionCode')} 入口页面:{record.get('url')}
  16. </p>
  17. );
  18. }
  19. @observer
  20. class AddChildButton extends React.Component {
  21. render() {
  22. const { dataSet, ...otherProps } = this.props;
  23. const { current } = dataSet;
  24. return <Button {...otherProps} disabled={!current || !current.get('id')} />;
  25. }
  26. }
  27. class App extends React.Component {
  28. ds = new DataSet({
  29. primaryKey: 'id',
  30. queryUrl: '/tree.mock',
  31. submitUrl: '/tree.mock',
  32. autoQuery: true,
  33. parentField: 'parentId',
  34. idField: 'id',
  35. checkField: 'ischecked',
  36. fields: [
  37. { name: 'id', type: 'number' },
  38. { name: 'text', type: 'string', label: '功能名称' },
  39. { name: 'url', type: 'string', label: '入口页面' },
  40. { name: 'expand', type: 'boolean', label: '是否展开' },
  41. { name: 'ischecked', type: 'boolean', label: '是否开启' },
  42. { name: 'score', type: 'number', order: 'asc' },
  43. { name: 'parentId', type: 'number', parentFieldName: 'id' },
  44. ],
  45. events: {
  46. indexchange: ({ current }) => console.log('current user', current),
  47. submit: ({ data }) => console.log('submit tree data', data),
  48. },
  49. });
  50. state = {
  51. expandIconColumnIndex: 0,

树形数据异步懒加载

点击展开图标时异步加载子数据。

Table表格 - 图7

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, Icon, Spin } from 'choerodon-ui/pro';
  4. import { observer } from 'mobx-react';
  5. import axios from 'axios';
  6. import classNames from 'classnames';
  7. const { Column } = Table;
  8. function iconRenderer({ record, text }) {
  9. return [
  10. <Icon key="icon" type={record.get('icon')} />,
  11. <span key="text">{text}</span>,
  12. ];
  13. }
  14. function expandedRowRenderer({ record }) {
  15. return (
  16. <p style={{ display: 'none' }}>
  17. 功能代码:{record.get('functionCode')} 入口页面:{record.get('url')}
  18. </p>
  19. );
  20. }
  21. // icon 渲染问题, 首先判断record的值和自定义状态来判断出叶节点和父节点进行不同的渲染
  22. function expandicon({
  23. prefixCls,
  24. expanded,
  25. expandable,
  26. needIndentSpaced,
  27. record,
  28. onExpand,
  29. }) {
  30. if (record.get('parentId')) {
  31. // 子结点渲染
  32. return <span style={{ paddingLeft: '0.18rem' }} />;
  33. }
  34. if (record.getState('loadding') === true) {
  35. // 自定义状态渲染
  36. return <Spin tip="loading" delay={200} size="small" />;
  37. }
  38. const iconPrefixCls = `${prefixCls}-expand-icon`;
  39. const classString = classNames(iconPrefixCls, {
  40. [`${iconPrefixCls}-expanded`]: expanded,
  41. });

树形数据异步分页

异步加载数据并对父亲节点进行分页处理。

Table表格 - 图8

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, Icon, Spin } from 'choerodon-ui/pro';
  4. import { observer } from 'mobx-react';
  5. import axios from 'axios';
  6. import classNames from 'classnames';
  7. const { Column } = Table;
  8. function iconRenderer({ record, text }) {
  9. return [
  10. <Icon key="icon" type={record.get('icon')} />,
  11. <span key="text">{text}</span>,
  12. ];
  13. }
  14. function expandedRowRenderer({ record }) {
  15. return (
  16. <p style={{ display: 'none' }}>
  17. 功能代码:{record.get('functionCode')} 入口页面:{record.get('url')}
  18. </p>
  19. );
  20. }
  21. // icon 渲染问题, 首先判断record的值和自定义状态来判断出叶节点和父节点进行不同的渲染
  22. function expandicon({
  23. prefixCls,
  24. expanded,
  25. expandable,
  26. needIndentSpaced,
  27. record,
  28. onExpand,
  29. }) {
  30. if (record.get('parentId')) {
  31. // 子结点渲染
  32. return <span style={{ paddingLeft: '0.18rem' }} />;
  33. }
  34. if (record.getState('loadding') === true) {
  35. // 自定义状态渲染
  36. return <Spin tip="loding" delay={200} size="small" />;
  37. }
  38. const iconPrefixCls = `${prefixCls}-expand-icon`;
  39. const classString = classNames(iconPrefixCls, {
  40. [`${iconPrefixCls}-expanded`]: expanded,
  41. });

组合列

组合表头展示列信息。

Table表格 - 图9

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table } from 'choerodon-ui/pro';
  4. const { Column } = Table;
  5. class App extends React.Component {
  6. ds = new DataSet({
  7. primaryKey: 'userid',
  8. name: 'user',
  9. autoQuery: true,
  10. pageSize: 5,
  11. fields: [
  12. { name: 'userid', type: 'string', label: '编号', required: true },
  13. { name: 'name', type: 'string', label: '姓名' },
  14. { name: 'age', type: 'number', label: '年龄', max: 100, step: 1 },
  15. {
  16. name: 'sex',
  17. type: 'string',
  18. label: '性别',
  19. lookupCode: 'HR.EMPLOYEE_GENDER',
  20. },
  21. {
  22. name: 'date.startDate',
  23. type: 'date',
  24. label: '开始日期',
  25. defaultValue: new Date(),
  26. },
  27. {
  28. name: 'sexMultiple',
  29. type: 'string',
  30. label: '性别(多值)',
  31. lookupCode: 'HR.EMPLOYEE_GENDER',
  32. multiple: true,
  33. },
  34. ],
  35. });
  36. render() {
  37. return (
  38. <Table dataSet={this.ds}>
  39. <Column header="组合">
  40. <Column name="name" width={100} />
  41. <Column name="age" />
  42. </Column>
  43. <Column header="组合3">
  44. <Column header="组合2">
  45. <Column name="sex" />
  46. <Column name="date.startDate" />
  47. </Column>

组合行

通过隐藏行实现行合并展示。

Table表格 - 图10

  1. /* eslint-disable no-plusplus */
  2. import React from 'react';
  3. import ReactDOM from 'react-dom';
  4. import { DataSet, Table } from 'choerodon-ui/pro';
  5. let needLoadFlag = true;
  6. const rowCombineArr = [];
  7. const transformData = (ds) => {
  8. const data = ds.toData();
  9. let currentName = null;
  10. let repeatNum = 0;
  11. let repeatStart = 0;
  12. for (let i = 0; i < data.length; i++) {
  13. const record = data[i];
  14. // 根据name进行合并
  15. const { name } = record;
  16. if (currentName === null) {
  17. currentName = name;
  18. repeatNum = 1;
  19. repeatStart = i;
  20. rowCombineArr[repeatStart] = 1;
  21. } else if (currentName === name) {
  22. rowCombineArr[i] = 0;
  23. repeatNum++;
  24. } else {
  25. currentName = null;
  26. rowCombineArr[repeatStart] = repeatNum;
  27. repeatNum = 0;
  28. i--;
  29. }
  30. if (i === data.length - 1) {
  31. rowCombineArr[repeatStart] = repeatNum;
  32. }
  33. }
  34. ds.loadData(data);
  35. };
  36. const newDataSet = {
  37. fields: [
  38. {
  39. name: 'name',
  40. type: 'string',
  41. label: 'name',

高级搜索条

Table queryBar 设为 advancedBar 展示高级搜索条。

Table表格 - 图11

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button } from 'choerodon-ui/pro';
  4. const optionData = [
  5. { text: '男', value: 'M' },
  6. { text: '女', value: 'F' },
  7. ];
  8. class App extends React.Component {
  9. optionDs = new DataSet({
  10. data: optionData,
  11. selection: 'single',
  12. });
  13. ds = new DataSet({
  14. primaryKey: 'userid',
  15. name: 'user',
  16. autoQuery: true,
  17. pageSize: 5,
  18. queryFields: [
  19. { name: 'name', type: 'string', label: '姓名' },
  20. { name: 'age', type: 'number', label: '年龄' },
  21. {
  22. name: 'sex.text',
  23. type: 'string',
  24. label: '性别',
  25. textField: 'text',
  26. valueField: 'value',
  27. options: this.optionDs, // 下拉框组件的菜单数据集
  28. defaultValue: 'F',
  29. },
  30. { name: 'date.startDate', type: 'date', label: '开始日期' },
  31. {
  32. name: 'sexMultiple',
  33. type: 'string',
  34. label: '性别(多值)',
  35. lookupCode: 'HR.EMPLOYEE_GENDER',
  36. multiple: true,
  37. },
  38. ],
  39. fields: [
  40. { name: 'userid', type: 'string', label: '编号', required: true },
  41. { name: 'name', type: 'string', label: '姓名' },
  42. { name: 'age', type: 'number', label: '年龄', max: 100, step: 1 },
  43. {
  44. name: 'sex',

过滤条

Table queryBar 设为 bar 展示过滤条。

Table表格 - 图12

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button } from 'choerodon-ui/pro';
  4. const config = {
  5. primaryKey: 'userid',
  6. name: 'user',
  7. autoQuery: true,
  8. pageSize: 5,
  9. queryFields: [
  10. { name: 'name', type: 'string', label: '姓名', defaultValue: 'Hugh' },
  11. { name: 'age', type: 'number', label: '年龄' },
  12. { name: 'code', type: 'object', label: '代码描述', lovCode: 'LOV_CODE' },
  13. {
  14. name: 'sex',
  15. type: 'string',
  16. label: '性别',
  17. lookupCode: 'HR.EMPLOYEE_GENDER',
  18. },
  19. { name: 'date.startDate', type: 'date', label: '开始日期' },
  20. {
  21. name: 'sexMultiple',
  22. type: 'string',
  23. label: '性别(多值)',
  24. lookupCode: 'HR.EMPLOYEE_GENDER',
  25. multiple: true,
  26. },
  27. ],
  28. fields: [
  29. { name: 'userid', type: 'string', label: '编号', required: true },
  30. { name: 'name', type: 'string', label: '姓名' },
  31. { name: 'age', type: 'number', label: '年龄', max: 100, step: 1 },
  32. {
  33. name: 'sex',
  34. type: 'string',
  35. label: '性别',
  36. lookupCode: 'HR.EMPLOYEE_GENDER',
  37. },
  38. {
  39. name: 'date.startDate',
  40. type: 'date',
  41. label: '开始日期',
  42. defaultValue: new Date(),
  43. },
  44. {
  45. name: 'sexMultiple',
  46. type: 'string',
  47. label: '性别(多值)',
  48. lookupCode: 'HR.EMPLOYEE_GENDER',
  49. multiple: true,
  50. },

专业搜索条

Table queryBar 设为 professionalBar 展示专业搜索条。

Table表格 - 图13

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table } from 'choerodon-ui/pro';
  4. const optionData = [
  5. { text: '男', value: 'M' },
  6. { text: '女', value: 'F' },
  7. ];
  8. class App extends React.Component {
  9. optionDs = new DataSet({
  10. data: optionData,
  11. selection: 'single',
  12. });
  13. ds = new DataSet({
  14. primaryKey: 'userid',
  15. name: 'user',
  16. autoQuery: true,
  17. pageSize: 5,
  18. queryFields: [
  19. { name: 'name', type: 'string', label: '姓名' },
  20. { name: 'age', type: 'number', label: '年龄' },
  21. {
  22. name: 'sex.text',
  23. type: 'string',
  24. label: '性别',
  25. textField: 'text',
  26. valueField: 'value',
  27. options: this.optionDs, // 下拉框组件的菜单数据集
  28. defaultValue: 'F',
  29. },
  30. { name: 'date.startDate', type: 'date', label: '开始日期' },
  31. {
  32. name: 'sexMultiple',
  33. type: 'string',
  34. label: '性别(多值)',
  35. lookupCode: 'HR.EMPLOYEE_GENDER',
  36. multiple: true,
  37. },
  38. ],
  39. fields: [
  40. { name: 'name', type: 'string', label: '姓名' },
  41. { name: 'age', type: 'number', label: '年龄' },
  42. {
  43. name: 'sex.text',
  44. type: 'string',
  45. label: '性别',
  46. textField: 'text',

自定义搜索条

queryBar 采用钩子类型自定义搜索条,预置搜索条组件可导出配合使用。

Table表格 - 图14

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, Form } from 'choerodon-ui/pro';
  4. const { FilterBar } = Table;
  5. const optionData = [
  6. { text: '男', value: 'M' },
  7. { text: '女', value: 'F' },
  8. ];
  9. class App extends React.Component {
  10. optionDs = new DataSet({
  11. data: optionData,
  12. selection: 'single',
  13. });
  14. ds = new DataSet({
  15. primaryKey: 'userid',
  16. name: 'user',
  17. autoQuery: true,
  18. pageSize: 5,
  19. queryFields: [
  20. { name: 'name', type: 'string', label: '姓名' },
  21. { name: 'age', type: 'number', label: '年龄' },
  22. {
  23. name: 'sex.text',
  24. type: 'string',
  25. label: '性别',
  26. textField: 'text',
  27. valueField: 'value',
  28. options: this.optionDs,
  29. },
  30. ],
  31. fields: [
  32. { name: 'userid', type: 'string', label: '编号', required: true },
  33. { name: 'name', type: 'string', label: '姓名' },
  34. { name: 'age', type: 'number', label: '年龄', max: 100, step: 1 },
  35. {
  36. name: 'sex',
  37. type: 'string',
  38. label: '性别',
  39. lookupCode: 'HR.EMPLOYEE_GENDER',
  40. },
  41. {
  42. name: 'date.startDate',
  43. type: 'date',
  44. label: '开始日期',
  45. defaultValue: new Date(),
  46. },
  47. {
  48. name: 'sexMultiple',
  49. type: 'string',
  50. label: '性别(多值)',

自定义查询 DataSet

自定义列表头部查询 DataSet,更灵活处理查询数据源逻辑。

Table表格 - 图15

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table } from 'choerodon-ui/pro';
  4. const { Column } = Table;
  5. class App extends React.Component {
  6. qds = new DataSet({
  7. autoQuery: true,
  8. name: 'user',
  9. pageSize: 1,
  10. fields: [
  11. { name: 'name', type: 'string', label: '姓名' },
  12. { name: 'age', type: 'number', label: '年龄' },
  13. {
  14. name: 'code',
  15. type: 'object',
  16. label: '代码描述',
  17. lovCode: 'LOV_CODE',
  18. },
  19. {
  20. name: 'code_code',
  21. type: 'string',
  22. label: '代码',
  23. maxLength: 20,
  24. bind: 'code.code',
  25. ignore: 'always',
  26. },
  27. {
  28. name: 'code_description',
  29. type: 'string',
  30. label: '代码描述',
  31. bind: 'code.description',
  32. ignore: 'always',
  33. },
  34. ],
  35. });
  36. ds = new DataSet({
  37. primaryKey: 'userid',
  38. name: 'user',
  39. autoQuery: true,
  40. pageSize: 5,
  41. queryDataSet: this.qds,
  42. selection: 'single',
  43. fields: [
  44. { name: 'userid', type: 'string', label: '编号', required: true },

Spin 受控

Table Spin 受控与自定义渲染展示。

Table表格 - 图16

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, message } from 'choerodon-ui/pro';
  4. const { Column } = Table;
  5. class App extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. spinProps: {},
  10. };
  11. }
  12. ds = new DataSet({
  13. primaryKey: 'userid',
  14. name: 'user',
  15. autoQuery: true,
  16. pageSize: 5,
  17. fields: [
  18. {
  19. name: 'userid',
  20. type: 'string',
  21. label: '编号',
  22. required: true,
  23. unique: true,
  24. help: '主键,区分用户',
  25. },
  26. { name: 'name', type: 'intl', label: '姓名' },
  27. {
  28. name: 'age',
  29. type: 'number',
  30. label: '年龄',
  31. unique: 'uniqueGroup',
  32. max: 100,
  33. step: 1,
  34. help: '用户年龄,可以排序',
  35. },
  36. ],
  37. });
  38. handleUp = () => {
  39. this.setState({
  40. spinProps: { indicator: this.c7nIcon, size: 'large', spinning: true },
  41. });
  42. message.success('启用自定义Spin');
  43. };

按钮受控

结合 mobx 处理一些按钮状态控制,避免在事件中使用 state 导致性能问题。

Table表格 - 图17

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { observer } from 'mobx-react-lite';
  4. import {
  5. DataSet,
  6. Table,
  7. Button,
  8. } from 'choerodon-ui/pro';
  9. const HeaderButtons = observer(props => {
  10. const isDisabled = props.dataSet.selected.length === 0;
  11. return (
  12. <Button icon="delete" disabled={isDisabled}>
  13. 删除
  14. </Button>
  15. );
  16. });
  17. const App = observer(() => {
  18. const userDs = new DataSet({
  19. primaryKey: 'userid',
  20. name: 'user',
  21. autoQuery: true,
  22. pageSize: 5,
  23. fields: [
  24. {
  25. name: 'userid',
  26. type: 'string',
  27. label: '编号',
  28. required: true,
  29. },
  30. {
  31. name: 'name',
  32. type: 'intl',
  33. label: '姓名',
  34. },
  35. {
  36. name: 'age',
  37. type: 'number',
  38. label: '年龄',
  39. max: 100,
  40. step: 1,
  41. },
  42. {
  43. name: 'sex',
  44. type: 'string',

动态配置字段编辑器

动态切换字段编辑器,根据字段基础的值来改变字段性别编辑器为 lov 或 select。

Table表格 - 图18

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table, Button, Switch, Select } from 'choerodon-ui/pro';
  4. const { Column } = Table;
  5. class App extends React.Component {
  6. optionDs = new DataSet({
  7. selection: 'single',
  8. queryUrl: '/common/code/HR.EMPLOYEE_GENDER/',
  9. autoQuery: true,
  10. });
  11. userDs = new DataSet({
  12. autoCreate: true,
  13. primaryKey: 'userid',
  14. name: 'user',
  15. pageSize: 5,
  16. fields: [
  17. {
  18. name: 'base',
  19. type: 'string',
  20. label: '基础',
  21. },
  22. {
  23. name: 'sex',
  24. label: '性别',
  25. dynamicProps: {
  26. type: ({ record }) => {
  27. return record.get('base') === 'Lov' ? 'object' : 'string';
  28. },
  29. lovCode: ({ record }) => {
  30. return record.get('base') === 'Lov' ? 'LOV_CODE' : null;
  31. },
  32. options: ({ record }) => {
  33. return record.get('base') === 'Lov' ? null : this.optionDs;
  34. },

自适应高度

通过 autoHeight 使得表格可以自适应容器高度,内容超出表内滚动。(需要父级元素非仅由 Table 撑开)。

autoHeight 属性:

类型默认值 / 自定义
booleanfalse
booleantrue = { type: ‘minHeight’, diff: 80 }
object{ type: ‘minHeight’ | ‘maxHeight’, diff: number(Table 自适应底部预留调整参数) }

Table表格 - 图19

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. Form,
  7. TextField,
  8. NumberField,
  9. SelectBox,
  10. Modal,
  11. Button,
  12. } from 'choerodon-ui/pro';
  13. import { observer } from 'mobx-react';
  14. const { Column } = Table;
  15. class App extends React.Component {
  16. userDs = new DataSet({
  17. primaryKey: 'userid',
  18. name: 'user',
  19. autoQuery: true,
  20. pageSize: 5,
  21. fields: [
  22. {
  23. name: 'userid',
  24. type: 'string',
  25. label: '编号',
  26. required: true,
  27. },
  28. {
  29. name: 'name',
  30. type: 'intl',
  31. label: '姓名',
  32. },
  33. {
  34. name: 'age',
  35. type: 'number',
  36. label: '年龄',
  37. max: 100,
  38. step: 1,
  39. },
  40. {
  41. name: 'sex',
  42. type: 'string',
  43. label: '性别',
  44. lookupCode: 'HR.EMPLOYEE_GENDER',
  45. required: true,
  46. },
  47. { name: 'enable', type: 'boolean', label: '是否开启' },
  48. ],
  49. });
  50. demoDs = new DataSet({
  51. autoCreate: true,
  52. fields: [

虚拟滚动

虚拟滚动,virtual 配合 height 使用。

当前版本还有一些问题,拖动滚动不顺滑等,非必需情况(大数据需求并同时对功能性需求很高)下使用建议不使用。

后续会不断完善此功能,感谢理解。

Table表格 - 图20

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { DataSet, Table } from 'choerodon-ui/pro';
  4. class App extends React.Component {
  5. userDs = new DataSet({
  6. primaryKey: 'userid',
  7. name: 'user',
  8. autoQuery: true,
  9. pageSize: 10,
  10. fields: [
  11. {
  12. name: 'userid',
  13. type: 'string',
  14. label: '编号',
  15. required: true,
  16. unique: true, // 唯一索引或联合唯一索引组名 设置可编辑只有新增才能编辑,确保该字段或字段组唯一性
  17. help: '主键,区分用户',
  18. },
  19. {
  20. name: 'name',
  21. type: 'intl',
  22. label: '姓名',
  23. },
  24. {
  25. name: 'age',
  26. type: 'number',
  27. label: '年龄',
  28. unique: 'uniqueGroup',
  29. max: 100,
  30. step: 1,
  31. help: '用户年龄,可以排序',
  32. },
  33. {
  34. name: 'numberMultiple',
  35. type: 'number',
  36. label: '数值多值',
  37. multiple: true,
  38. min: 10,
  39. max: 100,
  40. step: 0.5,
  41. },
  42. {
  43. name: 'code',
  44. type: 'object',
  45. label: '代码描述',
  46. },

拖拽集成

拖拽集成,点击对应按钮查看不同类型拖拽示例。

Table表格 - 图21

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. Form,
  7. TextField,
  8. NumberField,
  9. SelectBox,
  10. Modal,
  11. Button,
  12. } from 'choerodon-ui/pro';
  13. const { Column } = Table;
  14. class EditButton extends React.Component {
  15. handleClick = e => {
  16. const { record, onClick } = this.props;
  17. onClick(record, e);
  18. };
  19. render() {
  20. return <Button funcType="flat" icon="mode_edit" onClick={this.handleClick} size="small" />;
  21. }
  22. }
  23. class App extends React.Component {
  24. constructor(props) {
  25. super(props);
  26. this.state = {
  27. dragColumnAlign: undefined,
  28. };
  29. }
  30. userDs = new DataSet({
  31. primaryKey: 'userid',
  32. name: 'user',
  33. autoQuery: true,
  34. pageSize: 5,
  35. fields: [
  36. {
  37. name: 'userid',
  38. type: 'string',
  39. label: '编号',
  40. required: true,
  41. },
  42. {
  43. name: 'name',
  44. type: 'intl',

表头编辑

支持对列 header 编辑以及列的位置拖拽修改,触发对应的事件获取信息进行处理。

Table表格 - 图22

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. Form,
  7. TextField,
  8. NumberField,
  9. SelectBox,
  10. Modal,
  11. Button,
  12. } from 'choerodon-ui/pro';
  13. const { Column } = Table;
  14. class EditButton extends React.Component {
  15. handleClick = (e) => {
  16. const { record, onClick } = this.props;
  17. onClick(record, e);
  18. };
  19. render() {
  20. return (
  21. <Button
  22. funcType="flat"
  23. icon="mode_edit"
  24. onClick={this.handleClick}
  25. size="small"
  26. />
  27. );
  28. }
  29. }
  30. const columnsNew = [
  31. { name: 'age', header: '芳龄' },
  32. { name: 'name', header: '贵姓' },
  33. { name: 'userid', header: '排位' },
  34. { name: 'enable', header: '甄选' },
  35. ];
  36. class App extends React.Component {
  37. constructor(props) {
  38. super(props);
  39. this.state = {
  40. editColumns: 'order',
  41. columnsNew: columnsNew,
  42. isDragColumn: true,
  43. };
  44. }

拖拽渲染示例

可以通过 rowDragRender 里面方法进行对于整体的拖拽控制,如 droppableProps,droppableProps 控制是否可以拖动和放入等。 更多查看 react-beautiful-dnd。

Table表格 - 图23

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. Form,
  7. TextField,
  8. NumberField,
  9. SelectBox,
  10. Modal,
  11. Button,
  12. } from 'choerodon-ui/pro';
  13. const { Column } = Table;
  14. const { TableRow } = Table;
  15. class EditButton extends React.Component {
  16. handleClick = (e) => {
  17. const { record, onClick } = this.props;
  18. onClick(record, e);
  19. };
  20. render() {
  21. return (
  22. <Button
  23. funcType="flat"
  24. icon="mode_edit"
  25. onClick={this.handleClick}
  26. size="small"
  27. />
  28. );
  29. }
  30. }
  31. class App extends React.Component {
  32. userDs = new DataSet({
  33. primaryKey: 'userid',
  34. name: 'user',
  35. autoQuery: true,
  36. pageSize: 5,
  37. fields: [
  38. {
  39. name: 'userid',
  40. type: 'string',
  41. label: '编号',
  42. required: true,
  43. },

功能总和

极其复杂的案例,通过操作了解更多 Table 功能。

Table表格 - 图24

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {
  4. DataSet,
  5. Table,
  6. NumberField,
  7. DateTimePicker,
  8. SelectBox,
  9. Modal,
  10. Button,
  11. AutoComplete,
  12. } from 'choerodon-ui/pro';
  13. const { Column } = Table;
  14. function sexIdRenderer({ record }) {
  15. // 获取性别codeValueId
  16. return record.getField('sex').getLookupData().codeValueId;
  17. }
  18. function handleUserDSLoad({ dataSet }) {
  19. const first = dataSet.get(0);
  20. if (first) {
  21. first.selectable = false;
  22. }
  23. }
  24. function renderColumnFooter(dataset, name) {
  25. const max = Math.max(
  26. 0,
  27. ...dataset.data
  28. .map((record) => record.get(name))
  29. .filter((value) => !isNaN(value)),
  30. );
  31. return `最大年龄:${NumberField.format(max)}`;
  32. }
  33. function renderColumnHeader(dataset, name) {
  34. const field = dataset.getField(name);
  35. return (
  36. <span>
  37. <i>-=</i>
  38. {field ? field.get('label') : ''}
  39. <i>=-</i>
  40. </span>
  41. );
  42. }
  43. const codeDynamicProps = {
  44. lovCode({ record }) {
  45. if (record) {
  46. return 'LOV_CODE';
  47. }
  48. },
  49. };
  50. const nameDynamicProps = {

API

Table

参数说明类型默认值
header表头ReactNode | (records) => ReactNode
footer表脚ReactNode | (records) => ReactNode
border是否显示边框booleantrue
autoFocus是否新增行自动获焦至第一个可编辑字段booleanfalse
selectionMode选择记录的模式, 可选值: rowbox | click | dblclick | mousedown | nonestringrowbox
alwaysShowRowBox是否一直显示 rowbox,开启后在其他模式下也会显示 rowboxbooleanfalse
onRow设置行属性({ dataSet, record, index, expandedRow }) => object
buttons功能按钮,内置按钮可添加 afterClick 钩子,用于执行除了默认行为外的动作,可选值:add delete remove save query reset expandAll collapseAll export 或 数组 或 自定义按钮,数组为可选值字符串+按钮配置属性对象string | [string, object] | ReactNode | object
queryFields自定义查询字段组件或默认组件属性,默认会根据 queryDataSet 中定义的 field 类型自动匹配组件ReactNode[] | object
queryFieldsLimit头部显示的查询字段的数量,超出限制的查询字段放入弹出窗口number
queryBar查询条, 可选值为钩子或者内置类型:filterBar | professionalBar | advancedBar | normal | bar | nonestring | ({ dataSet, queryDataSet, buttons, pagination, queryFields, queryFieldsLimit }) => ReactNodenormal
summaryBar汇总条, 可选值为钩子或者字段 namestring | ({ dataSet, summaryFieldsLimit }) => ReactNode
summaryFieldsLimit头部显示的汇总字段的数量,超出限制的查询字段收起number
useMouseBatchChoose是否使用鼠标批量选择,开启后在 rowbox 的情况下可以进行鼠标拖动批量选择,在起始的 rowbox 处按下,在结束位置松开booleanfalse
rowHeight行高number | auto30
defaultRowExpanded默认行是否展开,当 dataSet 没有设置 expandField 时才有效booleanfalse
expandRowByClick通过点击行来展开子行booleanfalse
expandedRowRenderer展开行渲染器({ dataSet, record }) => ReactNode
expandIcon自定义展开图标({ prefixCls, expanded, expandable, needIndentSpaced, record, onExpand }) => ReactNode
expandIconColumnIndex展开图标所在列索引number
expandIconAsCell展开图标是否单独单元格展示booleantrue | false(tree mode)
indentSize展示树形数据时,每层缩进的宽度number15
filter数据过滤, 返回值 true - 显示 false - 不显示(record) => boolean
mode表格展示的模式,tree 需要配合 dataSet 的 idField 和 parentField 来展示,可选值: list | treestringlist
editMode表格编辑的模式,可选值: cell | inlinestringcell
filterBarFieldNamequeryBarbar时,直接输入的过滤条件的字段名stringparams
filterBarPlaceholderqueryBarbar时输入框的占位符string
pagination分页器,参考配置项pagination,设为 false 时不展示分页object | false
highLightRow当前行高亮booleantrue
selectedHighLightRow勾选行高亮booleanfalse
columnResizable可调整列宽booleantrue
pristine显示原始值booleanfalse
onExpand点击展开图标时触发(expanded, record) => void
virtual是否开启虚拟滚动,当设置表格高度时有效booleanfalse
virtualSpin是否开启虚拟滚动 Spinbooleanfalse
autoHeight是否开启高度自适应boolean | { type: ‘minHeight’ | ‘maxHeight’, diff: number(80) }false
autoFootHeight是否开启是否单独处理 column footerbooleanfalse
autoFocus是否新增行自动获焦至第一个可编辑字段booleanfalse
editorNextKeyEnterDown是否开启回车跳转下一行编辑booleantrue
autoMaxWidth是否开启双击侧边栏宽度最大自适应, 初次双击为最大值再次双击为 minWidthbooleanfalse
dragColumnAlign增加一个可拖拽列,实现行拖拽left | right
dragColumn打开列拖拽,组合列无法使用booleanfalse
dragRow行拖拽,实现行的拖拽,会导致拖拽列的一些事件失效,可以用dragColumnAlign来避免,树形数据无法使用booleanfalse
onDragEnd完成拖拽后的触发事件(dataSet, columns, resultDrag, provided) => void
columnsDragRender控制列的拖拽渲染请查看DragRender配置项
rowDragRender控制列的拖拽渲染请查看DragRender配置项
columnsMergeCoverage优先级高于columns,实现表头文字修改自定义修改和列的位置自定义修改ColumnProps[][]
columnsOnChange拖拽列和修改表头文字触发事件(change: ChangeColumns) => void
columnsEditType合并列信息选择,目前可以选择表头文字或者表的位置进行合并order | all | header
onDragEndBefore完成拖拽后,切换位置之前的触发事件(dataSet, columns, resultDrag, provided) => false | void |resultDrag
keyboard开启关闭新增的快捷按钮事件booleanfalse
dynamicFilterBarqueryBarfilterBar 时筛选条属性配置DynamicFilterBarConfig

更多属性请参考 DataSetComponent

Table.Column

参数说明类型默认值
name列对照的字段名string
width列宽,不推荐给所有列设置宽度,而是给某一列不设置宽度达到自动宽度的效果number
minWidth最小列宽number100
header列头ReactNode | (dataSet, name) => ReactNode
footer列脚ReactNode | (dataSet, name) => ReactNode
renderer单元格渲染回调({ value, text, name, record, dataSet }) => ReactNode
editor编辑器, 设为 true 时会根据 field 的 type 自动匹配编辑器。不可编辑请使用 false 值,而不是在控件上加 disabled。FormField | ((record, name) => FormField | boolean) | boolean
lock是否锁定, 可选值 false | true | ‘left’ | ‘right’boolean| stringfalse
align文字对齐方式,可选值: left | center | rightstring
resizable是否可调整宽度booleantrue
sortable是否可排序(后端请求排序,前端排序请自定义 header 自行实现)booleanfalse
style列单元格内链样式object
className列单元格样式名string
headerStyle列头内链样式object
headerClassName列头样式名string
footerStyle列脚内链样式object
footerClassName列脚样式名string
help额外信息,常用于提示string
showHelp展示提示信息的方式。可选值 tooltip | newLine | nonestringtooltip
onCell设置单元格属性({ dataSet, record, column }) => object
command行操作按钮集,该值为数组 或 返回数组的钩子,内置按钮可添加 afterClick 钩子,用于执行除了默认行为外的动作,数组可选值:edit delete 或 [edit| delete , 按钮配置属性对象] 或 自定义按钮(string | [string, object] | ReactNode)[] | ({ dataSet, record }) => (string | [string, object] | ReactNode | object )[]
hidden隐藏boolean
tooltip用 Tooltip 显示单元格内容。可选值 none | always | overflowstringnone

Table.FilterBar

参数说明类型默认值
paramName输入的过滤条件的字段名stringparams
placeholder输入框的占位符string过滤表

更多属性请参考 Table queryBar 属性的钩子参数。

Table.AdvancedQueryBar & Table.ProfessionalBar

参数说明类型默认值
queryFieldsLimit头部显示的查询字段的数量,超出限制的查询字段放入弹出窗口number1

更多属性请参考 Table queryBar 属性的钩子参数。

Table.ToolBar

参数说明类型默认值
queryFieldsLimit头部显示的查询字段的数量,超出限制的查询字段放入弹出窗口number1
pagination分页器,参考paginationPaginationComponent

更多属性请参考 Table queryBar 属性的钩子参数。

pagination

分页的配置项。

参数说明类型默认值
position指定分页显示的位置top | bottom | bothbottom

dragRender

可以满足自定义更多的渲染需求,注意会覆盖默认值,建议阅读中文地址react-beautiful-dnd 以及当前代码示例。 控制 renderClone 拖拽起来的时候会在 body 下面新增加一个 table 会在这个 table 注入元素比如下面的示例可以实现在类名为 c7n-pro-table-drag-container 的 table 里面渲染对应的元素,这里你可以增加样式覆盖完成你想要的拖拽样式,由于拖拽使用的 Fixed 定位所以会导致 table 长度变化,可以根据业务修改合适的 columns 的宽度来让表现更加自然。renderIcon 来渲染拖拽的自定义 Icon。

可以注意一下设置 新增拖拽例的key值 DRAG_KEY = ‘drag-column‘; 防止拖拽在dom结构外报错的table 类名 c7n-pro-table-drag-container

参数说明类型
droppablePropsdroppableProps 参考文档object
draggablePropsDraggableProps 参考文档object
renderClone拖拽起来的时候会在 body 下面新增加一个 table 会在这个 table 注入元素(DragTableRowProps | DragTableHeaderCellProps) => ReactElement
renderIcon可以自定义图标图标当为 row 时候({record})=> ReactElement 为column 时候 ({column,dataSet, snapshot})=> ReactElement

spin

spin 的配置项。

参数说明类型
indicator加载指示符ReactElement
spinning是否旋转boolean

更多案列和属性请参考 Spin

分页配置

分页功能配置可以按照如下配置进行全局配置

  1. import { configure } from 'choerodon-ui';
  2. configure({
  3. pagination: { pageSizeOptions: ['10', '20', '50', '100', '1000'] },
  4. });

全局配置操作,建议在初始化的时候进行。更多的配置参考pagination;

导出配置

可以根据需求进行全局配置,和局部配置

  1. import { configure } from 'choerodon-ui';
  2. import { DataSet } from 'choerodon-ui/pro';
  3. // 全局配置
  4. const basicUrl = ``;
  5. configure({
  6. transport: {
  7. exports: ({ dataSet, name: fieldName }) => {
  8. const _token = dataSet.current.get('_token');
  9. return {
  10. url: `${basicUrl}/v1/export`,
  11. method: 'POST',
  12. params: { _token, fieldName },
  13. transformResponse: (res) => {
  14. try {
  15. const aLink = document.createElement('a');
  16. const blob = new Blob([res.data], {
  17. type: 'application/vnd.ms-excel',
  18. });
  19. aLink.href = URL.createObjectURL(blob);
  20. aLink.download = fieldName;
  21. aLink.click();
  22. document.body.appendChild(aLink);
  23. } catch (e) {
  24. // do nothing, use default error deal
  25. }
  26. },
  27. };
  28. },
  29. },
  30. });
  31. // 局部使用
  32. // eslint-disable-next-line no-unused-vars
  33. const tableDs = new DataSet({
  34. primaryKey: 'userid',
  35. name: 'user',
  36. autoQuery: true,
  37. pageSize: 5,
  38. cacheSelection: true,
  39. transport: {
  40. exports: ({ dataSet }) => {
  41. const fileId = dataSet.name;
  42. return {
  43. url: `/_api/table/${fileId}`,
  44. method: 'get',
  45. };
  46. },
  47. },
  48. });

新增快捷键

keyboard 控制是否开启

  • Alt + n,焦点在 table 单元格内(非 querybar 区)时,新增行(代码可配置是首行还是末行新建)
  • Ctrl + s,焦点在table单元格,则保存当前 table
  • Ctrl + d(或 Command + d):
  • 焦点在 table 单元格,则复制上一行的单元格内容
  • 焦点在 table 某行, 则复制上一行的所有单元格内容
  • Delete,当前焦点元素内时,删除 1 个字符
  • Alt + delete,焦点在 table 单元格内,删除当前行,弹出二次提示框
  • Shift + 方向键,焦点在 table 某行,当前 table 可多选的情况,可选择多行

局部的使用 demo 方法参见Table;