Table 表格

展示行列数据。

何时使用#

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

如何使用#

指定表格的数据源 dataSource 为一个数组。

const dataSource = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}];

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  key: 'name',
}, {
  title: '年龄',
  dataIndex: 'age',
  key: 'age',
}, {
  title: '住址',
  dataIndex: 'address',
  key: 'address',
}];

<Table dataSource={dataSource} columns={columns} />

注:dataSource0.11.0 版本后不再支持远程模式。

API#

Table#

参数 说明 类型 默认值
rowSelection 列表项是否可选择,配置项 Object null
pagination 分页器,配置项参考 pagination,设为 false 时不显示分页 Object
size 正常或迷你类型,default or small String default
dataSource 数据数组 Array
columns 表格列的配置描述,具体项见下表 Array -
rowKey 表格行 key 的取值 Function(record, index):string record.key
rowClassName 表格行的类名 Function(record, index):string -
expandedRowRender 额外的展开行 Function -
defaultExpandedRowKeys 默认展开的行 Array -
onChange 分页、排序、筛选变化时触发 Function(pagination, filters, sorter)
loading 页面是否加载中 Boolean false
locale 默认文案设置,目前包括排序、过滤、空数据文案 Object filterConfirm: '确定'
filterReset: '重置'
emptyText: '暂无数据'
默认值
indentSize 展示树形数据时,每层缩进的宽度,以 px 为单位 Number 15
onRowClick 处理行点击事件 Function(record, index) -
useFixedHeader 是否固定表头 Boolean false
bordered 是否展示外边框和列边框 Boolean false
showHeader 是否显示表头 Boolean true
footer 表格底部自定义渲染函数 Function(currentPageData)

Column#

列描述数据对象,是 columns 中的一项。

参数 说明 类型 默认值
title 列头显示文字 String or React.Element
key React 需要的 key,建议设置 String
dataIndex 列数据在数据项中对应的 key String
render 生成复杂数据的渲染函数,参数分别为当前列的值,当前列数据,列索引,@return里面可以设置表格行/列合并 Function(text, record, index) {}
filters 表头的筛选菜单项 Array
onFilter 本地模式下,确定筛选的运行函数 Function
filterMultiple 是否多选 Boolean true
sorter 排序函数,本地排序使用一个函数,需要服务端排序可设为 true Function or Boolean -
colSpan 表头列合并,设置为 0 时,不渲染 Number
width 列宽度 String or Number -
className 列的 className String -

rowSelection#

选择功能的配置。

参数 说明 类型 默认值
type 多选/单选,checkbox or radio String checkbox
selectedRowKeys 指定选中项的 key 数组,需要和 onChange 进行配合 Array []
onChange 选中项发生变化的时的回调 Function(selectedRowKeys, selectedRows) -
getCheckboxProps 选择框的默认属性配置 Function(record) -
onSelect 用户手动选择/取消选择某列的回调 Function(record, selected, selectedRows) -
onSelectAll 用户手动选择/取消选择所有列的回调 Function(selected, selectedRows, changeRows) -

注意#

按照 React 的规范,所有的组件数组必须绑定 key。在 Table 中,dataSourcecolumns 里的数据值都需要指定 key 值。对于 dataSource 默认将每列数据的 key 属性作为唯一的标识。

如果你的数据没有这个属性,务必使用 rowKey 来指定数据列的主键。若没有指定,控制台会出现以下的提示,表格组件也会出现各类奇怪的错误。

// 比如你的数据主键是 uid
return <Table rowKey={record => record.uid} />;

代码演示

import { Table, Icon } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  key: 'name',
  render(text) {
    return <a href="#">{text}</a>;
  }
}, {
  title: '年龄',
  dataIndex: 'age',
  key: 'age',
}, {
  title: '住址',
  dataIndex: 'address',
  key: 'address',
}, {
  title: '操作',
  key: 'operation',
  render(text, record) {
    return (
      <span>
        <a href="#">操作一{record.name}</a>
        <span className="ant-divider"></span>
        <a href="#">操作二</a>
        <span className="ant-divider"></span>
        <a href="#" className="ant-dropdown-link">
          更多 <Icon type="down" />
        </a>
      </span>
    );
  }
}];
const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '西湖区湖底公园1号'
}];

ReactDOM.render(<Table columns={columns} dataSource={data} />
, mountNode);

简单的表格,最后一列是各种操作。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  render(text) {
    return <a href="#">{text}</a>;
  }
}, {
  title: '年龄',
  dataIndex: 'age'
}, {
  title: '住址',
  dataIndex: 'address'
}];
const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '西湖区湖底公园1号'
}];

// 通过 rowSelection 对象表明需要行选择
const rowSelection = {
  onChange(selectedRowKeys, selectedRows) {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  },
  onSelect(record, selected, selectedRows) {
    console.log(record, selected, selectedRows);
  },
  onSelectAll(selected, selectedRows, changeRows) {
    console.log(selected, selectedRows, changeRows);
  },
};

ReactDOM.render(<Table rowSelection={rowSelection} columns={columns} dataSource={data} />
, mountNode);

第一列是联动的选择框。

import { Table, Button } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
}, {
  title: '年龄',
  dataIndex: 'age',
}, {
  title: '住址',
  dataIndex: 'address',
}];

const data = [];
for (let i = 0; i < 46; i++) {
  data.push({
    key: i,
    name: `李大嘴${i}`,
    age: 32,
    address: `西湖区湖底公园${i}号`
  });
}

const App = React.createClass({
  getInitialState() {
    return {
      selectedRowKeys: [],  // 这里配置默认勾选列
      loading: false,
    };
  },
  start() {
    this.setState({ loading: true });
    // 模拟 ajax 请求,完成后清空
    setTimeout(() => {
      this.setState({
        selectedRowKeys: [],
        loading: false,
      });
    }, 1000);
  },
  onSelectChange(selectedRowKeys) {
    console.log('selectedRowKeys changed: ', selectedRowKeys);
    this.setState({ selectedRowKeys });
  },
  render() {
    const { loading, selectedRowKeys } = this.state;
    const rowSelection = {
      selectedRowKeys,
      onChange: this.onSelectChange,
    };
    const hasSelected = selectedRowKeys.length > 0;
    return (
      <div>
        <div style={{ marginBottom: 16 }}>
           <Button type="primary" onClick={this.start}
             disabled={!hasSelected} loading={loading}>操作</Button>
           <span style={{ marginLeft: 8 }}>{hasSelected ? `选择了 ${selectedRowKeys.length} 个对象` : ''}</span>
        </div>
        <Table rowSelection={rowSelection} columns={columns} dataSource={data} />
      </div>
    );
  }
});

ReactDOM.render(<App />, mountNode);

选择后进行操作,完成后清空选择,通过 rowSelection.selectedRowKeys 来控制选中项。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  render: text => <a href="#">{text}</a>,
}, {
  title: '年龄',
  dataIndex: 'age'
}, {
  title: '住址',
  dataIndex: 'address'
}];
const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '西湖区湖底公园1号'
}];

// 通过 rowSelection 对象表明需要行选择
const rowSelection = {
  getCheckboxProps(record) {
    return {
      disabled: record.name === '胡彦祖'    // 配置无法勾选的列
    };
  },
};

ReactDOM.render(<Table rowSelection={rowSelection} columns={columns} dataSource={data} />
, mountNode);

配置选择框的默认属性。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  render(text) {
    return <a href="#">{text}</a>;
  }
}, {
  title: '年龄',
  dataIndex: 'age'
}, {
  title: '住址',
  dataIndex: 'address'
}];

const data = [];
for (let i = 0; i < 46; i++) {
  data.push({
    key: i,
    name: `李大嘴${i}`,
    age: 32,
    address: `西湖区湖底公园${i}号`
  });
}

const pagination = {
  total: data.length,
  showSizeChanger: true,
  onShowSizeChange(current, pageSize) {
    console.log('Current: ', current, '; PageSize: ', pageSize);
  },
  onChange(current) {
    console.log('Current: ', current);
  }
};

ReactDOM.render(<Table columns={columns} dataSource={data} pagination={pagination} />
, mountNode);

数据项较多时显示分页。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  filters: [{
    text: '姓李的',
    value: '李',
  }, {
    text: '姓胡的',
    value: '胡',
  }, {
    text: '子菜单',
    value: '子菜单',
    children: [{
      text: '姓陈的',
      value: '陈',
    }, {
      text: '姓王的',
      value: '王',
    }],
  }],
  // 指定确定筛选的条件函数
  // 这里是名字中第一个字是 value
  onFilter: (value, record) => record.name.indexOf(value) === 0,
  sorter: (a, b) => a.name.length - b.name.length,
}, {
  title: '年龄',
  dataIndex: 'age',
  sorter: (a, b) => a.age - b.age,
}, {
  title: '地址',
  dataIndex: 'address',
  filters: [{
    text: '南湖',
    value: '南湖',
  }, {
    text: '西湖',
    value: '西湖',
  }],
  filterMultiple: false,
  onFilter: (value, record) => record.address.indexOf(value) === 0,
  sorter: (a, b) => a.address.length - b.address.length,
}];

const data = [{
  key: '1',
  name: '胡斌',
  age: 32,
  address: '南湖区湖底公园1号',
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园12号',
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '南湖区湖底公园123号',
}, {
  key: '4',
  name: '李秀莲大嘴哥',
  age: 32,
  address: '西湖区湖底公园123号',
}];

function onChange(pagination, filters, sorter) {
  // 点击分页、筛选、排序时触发
  console.log('各类参数是', pagination, filters, sorter);
}

ReactDOM.render(<Table columns={columns} dataSource={data} onChange={onChange} />, mountNode);

对某一列数据进行筛选,使用列的 filter 属性来指定需要筛选菜单的列,onFilter 用于筛选当前数据,filterMultiple 用于指定多选和单选。

对某一列数据进行排序,通过指定列的 sorter 函数即可启动排序按钮。sorter: function(a, b) { ... }, a、b 为比较的两个列数据。

import { Table } from 'antd';
import reqwest from 'reqwest';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  filters: [
    { text: '姓李的', value: '李' },
    { text: '姓胡的', value: '胡' },
  ],
}, {
  title: '年龄',
  dataIndex: 'age',
  sorter: true,
}, {
  title: '住址',
  dataIndex: 'address',
}];

const Test = React.createClass({
  getInitialState() {
    return {
      data: [],
      pagination: {},
      loading: false,
    };
  },
  handleTableChange(pagination, filters, sorter) {
    const pager = this.state.pagination;
    pager.current = pagination.current;
    this.setState({
      pagination: pager,
    });
    this.fetch({
      pageSize: pagination.pageSize,
      currentPage: pagination.current,
      sortField: sorter.field,
      sortOrder: sorter.order,
      ...filters,
    });
  },
  fetch(params = {}) {
    console.log('请求参数:', params);
    this.setState({ loading: true });
    reqwest({
      url: 'demo/data.json',
      method: 'get',
      data: params,
      type: 'json',
      success: (result) => {
        const pagination = this.state.pagination;
        pagination.total = result.totalCount;
        this.setState({
          loading: false,
          data: result.data,
          pagination,
        });
      }
    });
  },
  componentDidMount() {
    this.fetch();
  },
  render() {
    return (
      <Table columns={columns}
        dataSource={this.state.data}
        pagination={this.state.pagination}
        loading={this.state.loading}
        onChange={this.handleTableChange} />
    );
  }
});

ReactDOM.render(<Test />, mountNode);

0.11.0 以后,dataSource 远程模式被移除,用户可以自行实现数据读取方式。

这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。

另外,本例也展示了筛选排序功能如何交给服务端实现,列不需要指定具体的 onFiltersorter 函数,而是在把筛选和排序的参数发到服务端来处理。

注意,此示例是静态数据模拟,展示数据不会变化,请打开网络面板查看请求。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name'
}, {
  title: '年龄',
  dataIndex: 'age'
}, {
  title: '住址',
  dataIndex: 'address'
}];

const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '西湖区湖底公园1号'
}];

ReactDOM.render(<Table columns={columns} dataSource={data} pagination={false} />
, mountNode);

传入 pagination 为 false 即可。此时表格将完整显示 dataSource 内的数据,不进行任何分页。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name'
}, {
  title: '年龄',
  dataIndex: 'age'
}, {
  title: '住址',
  dataIndex: 'address'
}];
const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '西湖区湖底公园1号'
}];

ReactDOM.render(<div>
  <h4>中号表格(紧凑型)</h4>
  <Table columns={columns} dataSource={data} size="middle" />
  <h4>小号表格</h4>
  <Table columns={columns} dataSource={data} size="small" />
</div>, mountNode);

紧凑型的列表, 中型列表用于需要数据紧凑展示的情况,小型列表只用于对话框内。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  render(text) {
    return <a href="#">{text}</a>;
  }
}, {
  title: '资产',
  className: 'column-money',
  dataIndex: 'money'
}, {
  title: '住址',
  dataIndex: 'address'
}];

const data = [{
  key: '1',
  name: '胡彦斌',
  money: '¥300,000.00',
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  money: '¥1,256,000.00',
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  money: '¥120,000.00',
  address: '西湖区湖底公园1号'
}];

ReactDOM.render(<Table columns={columns} dataSource={data} bordered />
, mountNode);
.column-money {
  text-align: right;
}

添加表格边框线,bordered

import { Table } from 'antd';

const columns = [
  { title: '姓名', dataIndex: 'name', key: 'name' },
  { title: '年龄', dataIndex: 'age', key: 'age' },
  { title: '住址', dataIndex: 'address', key: 'address' },
  { title: '操作', dataIndex: '', key: 'x', render: () => <a href="#">删除</a> }
];

const data = [
  { key: 1, name: '胡彦斌', age: 32, address: '西湖区湖底公园1号', description: '我是胡彦斌,今年32岁,住在西湖区湖底公园1号。' },
  { key: 2, name: '吴彦祖', age: 42, address: '西湖区湖底公园2号', description: '我是吴彦祖,今年42岁,住在西湖区湖底公园2号。' },
  { key: 3, name: '李大嘴', age: 32, address: '西湖区湖底公园3号', description: '我是李大嘴,今年32岁,住在西湖区湖底公园3号。' }
];

ReactDOM.render(
<Table columns={columns}
  expandedRowRender={record => <p>{record.description}</p>}
  dataSource={data}
  className="table" />
, mountNode);

当表格内容较多不能一次性完全展示时。

import { Table } from 'antd';

// 事例表中第四行合并了五列,除了第一列设置 colSpan = 5 外
// 其他列的第四行 colSpan = 0 (被合并掉,不会渲染)
const renderContent = function (value, row, index) {
  let obj = {
    children: value,
    props: {}
  };
  if (index === 4) {
    obj.props.colSpan = 0;
  }
  return obj;
};

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  render(text, row, index) {
    if (index < 4) {
      return <a href="#">{text}</a>;
    }
    return {
      children: <a href="#">{text}</a>,
      props: {
        colSpan: 5
      }
    };
  }
}, {
  title: '年龄',
  dataIndex: 'age',
  render: renderContent
}, {
  title: '家庭电话',
  colSpan: 2,
  dataIndex: 'tel',
  render(value, row, index) {
    let obj = {
      children: value,
      props: {}
    };
    // 第三列的第三行行合并
    if (index === 2) {
      obj.props.rowSpan = 2;
    }

    // 第三列的第四行被合并没了,设置 rowSpan = 0 直接不用渲染
    if (index === 3) {
      obj.props.rowSpan = 0;
    }

    if (index === 4) {
      obj.props.colSpan = 0;
    }
    return obj;
  }
}, {
  title: '手机号',
  colSpan: 0,
  dataIndex: 'phone',
  render: renderContent
}, {
  title: '住址',
  dataIndex: 'address',
  render: renderContent
}];

const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  tel: '0571-22098909',
  phone: 18889898989,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  tel: '0571-22098333',
  phone: 18889898888,
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  tel: '0575-22098909',
  phone: 18900010002,
  address: '西湖区湖底公园1号'
}, {
  key: '4',
  name: '李夫人',
  age: 18,
  tel: '0575-22098909',
  phone: 18900010002,
  address: '西湖区湖底公园1号'
}, {
  key: '5',
  name: '习大大',
  age: 18,
  tel: '0575-22098909',
  phone: 18900010002,
  address: '西湖区湖底公园1号'
}];

ReactDOM.render(<Table columns={columns} dataSource={data} bordered />
, mountNode);

表头只支持列合并,使用 column 里的 colSpan 进行设置。

表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。

import { Table, Button } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name'
}, {
  title: '年龄',
  dataIndex: 'age'
}, {
  title: '住址',
  dataIndex: 'address'
}];
const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
  address: '西湖区湖底公园1号'
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
  address: '西湖区湖底公园1号'
}, {
  key: '3',
  name: '李大嘴',
  age: 32,
  address: '西湖区湖底公园1号'
}];

const App = React.createClass({
  getInitialState() {
    return {
      loading: false
    };
  },
  toggleLoading() {
    this.setState({
      loading: !this.state.loading
    });
  },
  render() {
    return (
      <div>
        <Table columns={columns} dataSource={data} loading={this.state.loading} />
        <Button type="primary" onClick={this.toggleLoading}>切换 loading 状态</Button>
      </div>
    );
  }
});

ReactDOM.render(<App />, mountNode);

用属性 loading 控制表格加载中状态。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  width: 150,
}, {
  title: '年龄',
  dataIndex: 'age',
  width: 150,
}, {
  title: '住址',
  dataIndex: 'address',
}];

const data = [];
for (let i = 0; i < 100; i++) {
  data.push({
    key: i,
    name: `李大嘴${i}`,
    age: 32,
    address: `西湖区湖底公园${i}号`
  });
}

ReactDOM.render(
  <Table columns={columns} dataSource={data} pagination={{ pageSize: 50 }} useFixedHeader />
, mountNode);

方便一页内展示大量数据。

需要指定 column 的 width 属性,否则列头和内容可能不对齐。

import { Table } from 'antd';

const columns = [
  { title: '姓名', dataIndex: 'name', key: 'name' },
  { title: '年龄', dataIndex: 'age', key: 'age' },
  { title: '列1', dataIndex: 'age', key: '1' },
  { title: '列2', dataIndex: 'age', key: '2' },
  { title: '列3', dataIndex: 'age', key: '3' },
  { title: '列4', dataIndex: 'age', key: '4' },
  { title: '列5', dataIndex: 'age', key: '5' },
  { title: '列6', dataIndex: 'age', key: '6' },
  { title: '列7', dataIndex: 'age', key: '7' },
  { title: '列8', dataIndex: 'age', key: '8' },
  {
    title: '操作',
    key: 'operation',
    render() {
      return <a href="#">操作</a>;
    }
  },
];
const data = [{
  key: '1',
  name: '胡彦斌',
  age: 32,
}, {
  key: '2',
  name: '胡彦祖',
  age: 42,
}];

const App = React.createClass({
  render() {
    return <Table columns={columns} dataSource={data} columnsPageRange={[2, 9]} columnsPageSize={4} />;
  }
});

ReactDOM.render(<App />, mountNode);

对于列数很多的数据,可以进行横向的分页,通过切换符切换当前展现的列。

import { Table } from 'antd';

const columns = [{
  title: '姓名',
  dataIndex: 'name',
  key: 'name',
  width: '40%',
}, {
  title: '年龄',
  dataIndex: 'age',
  key: 'age',
  width: '30%',
}, {
  title: '住址',
  dataIndex: 'address',
  key: 'address',
  width: '30%',
}];

const data = [{
  key: 1,
  name: 'a',
  age: 32,
  address: '我是a',
  children: [{
    key: 11,
    name: 'aa',
    age: 33,
    address: '我是aa',
  }, {
    key: 12,
    name: 'ab',
    age: 33,
    address: '我是ab',
    children: [{
      key: 121,
      name: 'aba',
      age: 33,
      address: '我是aba',
    }],
  }, {
    key: 13,
    name: 'ac',
    age: 33,
    address: '我是ac',
    children: [{
      key: 131,
      name: 'aca',
      age: 33,
      address: '我是aca',
      children: [{
        key: 1311,
        name: 'acaa',
        age: 33,
        address: '我是acaa',
      }, {
        key: 1312,
        name: 'acab',
        age: 33,
        address: '我是acab',
      }],
    }],
  }],
}, {
  key: 2,
  name: 'b',
  age: 32,
  address: '我是b',
}];

// 通过 rowSelection 对象表明需要行选择
const rowSelection = {
  onChange(selectedRowKeys, selectedRows) {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  },
  onSelect(record, selected, selectedRows) {
    console.log(record, selected, selectedRows);
  },
  onSelectAll(selected, selectedRows, changeRows) {
    console.log(selected, selectedRows, changeRows);
  }
};

ReactDOM.render(
  <Table columns={columns} rowSelection={rowSelection} dataSource={data} />,
  mountNode
);

表格支持树形数据的展示,可以通过设置 indentSize 以控制每一层的缩进宽度。

注:暂不支持父子数据递归关联选择。