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} />
代码演示
基本用法
简单的表格,最后一列是各种操作。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Icon, Divider } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a href="#">{text}</a>,
}, {
title: 'Age',
dataIndex: 'age',
key: 'age',
}, {
title: 'Address',
dataIndex: 'address',
key: 'address',
}, {
title: '',
key: 'action',
render: (text, record) => (
<span>
<a href="#">Action 一 {record.name}</a>
<Divider type="vertical" />
<a href="#">Delete</a>
<Divider type="vertical" />
<a href="#" className="c7n-dropdown-link">
More actions <Icon type="down" />
</a>
</span>
),
}];
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
带边框
添加表格边框线,页头和页脚。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
render: text => <a href="#">{text}</a>,
}, {
title: 'Cash Assets',
className: 'column-money',
dataIndex: 'money',
}, {
title: 'Address',
dataIndex: 'address',
}];
const data = [{
key: '1',
name: 'John Brown',
money: '¥300,000.00',
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
money: '¥1,256,000.00',
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Joe Black',
money: '¥120,000.00',
address: 'Sidney No. 1 Lake Park',
}];
ReactDOM.render(
<Table
columns={columns}
dataSource={data}
bordered
title={() => 'Header'}
footer={() => 'Footer'}
/>,
document.getElementById('container'));
JSX 风格的 API
使用 JSX 风格的 API(2.5.0 以后引入)
这个只是一个描述
columns
的语法糖,所以你不能用其他组件去包裹Column
和ColumnGroup
。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Icon, Divider } from 'choerodon-ui';
const { Column, ColumnGroup } = Table;
const data = [{
key: '1',
firstName: 'John',
lastName: 'Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
firstName: 'Jim',
lastName: 'Green',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
firstName: 'Joe',
lastName: 'Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
}];
ReactDOM.render(
<Table dataSource={data}>
<ColumnGroup title="Name">
<Column
title="First Name"
dataIndex="firstName"
key="firstName"
/>
<Column
title="Last Name"
dataIndex="lastName"
key="lastName"
/>
</ColumnGroup>
<Column
title="Age"
dataIndex="age"
key="age"
/>
<Column
title="Address"
dataIndex="address"
可选择
第一列是联动的选择框。
默认点击 checkbox 触发选择行为,需要点击行触发可以参考例子:https://codesandbox.io/s/000vqw38rl
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
render: text => <a href="#">{text}</a>,
}, {
title: 'Age',
dataIndex: 'age',
}, {
title: 'Address',
dataIndex: 'address',
}];
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
}, {
key: '4',
name: 'Disabled User',
age: 99,
address: 'Sidney No. 1 Lake Park',
}];
// rowSelection object indicates the need for row selection
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
getCheckboxProps: record => ({
disabled: record.name === 'Disabled User', // Column configuration not to be checked
name: record.name,
}),
selections: true,
};
选择和操作
选择后进行操作,完成后清空选择,通过 rowSelection.selectedRowKeys
来控制选中项。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Button } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
}, {
title: 'Age',
dataIndex: 'age',
}, {
title: 'Address',
dataIndex: 'address',
}];
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
});
}
class App extends React.Component {
state = {
selectedRowKeys: [], // Check here to configure the default column
loading: false,
};
start = () => {
this.setState({ loading: true });
// ajax request after empty completing
setTimeout(() => {
this.setState({
selectedRowKeys: [],
loading: false,
});
}, 1000);
}
onSelectChange = (selectedRowKeys) => {
console.log('selectedRowKeys changed: ', selectedRowKeys);
this.setState({ selectedRowKeys });
}
render() {
自定义选择项
通过 rowSelection.selections
自定义选择项,默认不显示下拉选项,设为 true
时显示默认选择项。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
}, {
title: 'Age',
dataIndex: 'age',
}, {
title: 'Address',
dataIndex: 'address',
}];
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
});
}
class App extends React.Component {
state = {
selectedRowKeys: [], // Check here to configure the default column
}
onSelectChange = (selectedRowKeys) => {
console.log('selectedRowKeys changed: ', selectedRowKeys);
this.setState({ selectedRowKeys });
}
render() {
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
hideDefaultSelections: true,
selections: [{
key: 'all-data',
text: 'Select All Data',
onSelect: () => {
this.setState({
selectedRowKeys: [...Array(46).keys()], // 0...45
});
下拉菜单筛选
设置 filterBar
属性为false来显示下拉过滤菜单。
对某一列数据进行筛选,使用列的 filters
属性来指定需要筛选菜单的列,onFilter
用于筛选当前数据,filterMultiple
用于指定多选和单选。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
filters: [{
text: 'Joe',
value: 'Joe',
}, {
text: 'Jim',
value: 'Jim',
}, {
text: 'Last Name',
value: 'last',
children: [{
text: 'Green',
value: 'Green',
}, {
text: 'Black',
value: 'Black',
}],
}],
// specify the condition of filtering result
// here is that finding the name started with `value`
onFilter: (value, record) => record.name.indexOf(value) > -1,
}, {
title: 'Age',
dataIndex: 'age',
filters: [],
onFilter: (value, record) => record.name.indexOf(value) === 0,
}, {
title: 'Address',
dataIndex: 'address',
filters: [{
text: 'London',
value: 'London',
}, {
text: 'New York',
value: 'New York',
}],
filterMultiple: true,
onFilter: (value, record) => record.address.indexOf(value) === 0,
}];
const data = [{
key: '1',
筛选和排序
对某一列数据进行筛选,使用列的 filters
属性来指定需要筛选菜单的列,onFilter
用于筛选当前数据,filterMultiple
用于指定多选和单选。
对某一列数据进行排序,通过指定列的 sorter
函数即可启动排序按钮。sorter: function(a, b) { ... }
, a、b 为比较的两个列数据。
使用 defaultSortOrder
属性,设置列的默认排序顺序。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
filters: [{
text: 'Joe',
value: 'Joe',
}, {
text: 'Jim',
value: 'Jim',
}],
// specify the condition of filtering result
// here is that finding the name started with `value`
onFilter: (value, record) => record.name.indexOf(value) === 0,
sorter: (a, b) => a.name.length - b.name.length,
}, {
title: 'Age',
dataIndex: 'age',
defaultSortOrder: 'descend',
sorter: (a, b) => a.age - b.age,
filters: [],
onFilter: (value, record) => record.age.toString().indexOf(value) === 0,
}, {
title: 'Address',
dataIndex: 'address',
filters: [{
text: 'London',
value: 'London',
}, {
text: 'New York',
value: 'New York',
}],
filterMultiple: false,
onFilter: (value, record) => record.address.indexOf(value) === 0,
sorter: (a, b) => a.address.length - b.address.length,
}];
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
可控的筛选和排序
使用受控属性对筛选和排序状态进行控制。
- columns 中定义了 filteredValue 和 sortOrder 属性即视为受控模式。
- 只支持同时对一列进行排序,请保证只有一列的 sortOrder 属性是生效的。
- 务必指定
column.key
。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Button } from 'choerodon-ui';
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
}, {
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
}];
function findText(value, filters) {
const found = filters.find(filter => filter.value === value);
return found ? found.text : value;
}
class App extends React.Component {
state = {
filteredInfo: { name: ['1'], address: ['a'] },
barFilters: ['No. 1'],
sortedInfo: null,
}
handleChange = (pagination, filters, sorter, barFilters) => {
console.log('Various parameters', pagination, filters, sorter, barFilters);
this.setState({
filteredInfo: filters,
sortedInfo: sorter,
barFilters,
});
}
clearFilters = () => {
自定义筛选菜单
通过 filterDropdown
、filterDropdownVisible
和 filterDropdownVisibleChange
定义自定义的列筛选功能,并实现一个搜索列的示例。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Input, Button, Icon } from 'choerodon-ui';
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Joe Black',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Jim Green',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
},
];
class App extends React.Component {
state = {
filterDropdownVisible: false,
data,
searchText: '',
filtered: false,
};
onInputChange = e => {
this.setState({ searchText: e.target.value });
};
onSearch = () => {
const { searchText } = this.state;
const reg = new RegExp(searchText, 'gi');
this.setState({
filterDropdownVisible: false,
远程加载数据
这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。
另外,本例也展示了筛选排序功能如何交给服务端实现,列不需要指定具体的 onFilter
和 sorter
函数,而是在把筛选和排序的参数发到服务端来处理。
注意,此示例使用 模拟接口,展示数据可能不准确,请打开网络面板查看请求。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
import reqwest from 'reqwest';
const columns = [
{
title: 'Name',
dataIndex: 'name',
sorter: true,
render: (name) => `${name.first} ${name.last}`,
width: '20%',
},
{
title: 'Gender',
dataIndex: 'gender',
filters: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
],
width: '20%',
},
{
title: 'Email',
dataIndex: 'email',
},
];
class App extends React.Component {
state = {
data: [],
pagination: {},
loading: false,
};
handleTableChange = (pagination, filters, sorter) => {
const pager = { ...this.state.pagination };
pager.current = pagination.current;
this.setState({
pagination: pager,
});
this.fetch({
results: pagination.pageSize,
page: pagination.current,
sortField: sorter.field,
sortOrder: sorter.order,
...filters,
});
紧凑型
三种紧凑型的列表,小型列表只用于对话框内。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
}, {
title: 'Age',
dataIndex: 'age',
}, {
title: 'Address',
dataIndex: 'address',
}];
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
}];
ReactDOM.render(
<div>
<h4>Large size table</h4>
<Table columns={columns} dataSource={data} size="large" />
<h4>Small size table</h4>
<Table columns={columns} dataSource={data} size="small" />
</div>,
document.getElementById('container'));
可展开
当表格内容较多不能一次性完全展示时。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Age', dataIndex: 'age', key: 'age' },
{ title: 'Address', dataIndex: 'address', key: 'address' },
{ title: 'Action', dataIndex: '', key: 'x', render: () => <a href="#">Delete</a> },
];
const data = [
{ key: 1, name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park', description: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.' },
{ key: 2, name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park', description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.' },
{ key: 3, name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park', description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.' },
];
ReactDOM.render(
<Table
columns={columns}
expandedRowRender={record => <p style={{ margin: 0 }}>{record.description}</p>}
dataSource={data}
/>,
document.getElementById('container'));
表格行/列合并
表头只支持列合并,使用 column 里的 colSpan 进行设置。
表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
// In the fifth row, other columns are merged into first column
// by setting it's colSpan to be 0
const renderContent = (value, row, index) => {
const obj = {
children: value,
props: {},
};
if (index === 4) {
obj.props.colSpan = 0;
}
return obj;
};
const columns = [{
title: 'Name',
dataIndex: 'name',
render: (text, row, index) => {
if (index < 4) {
return <a href="#">{text}</a>;
}
return {
children: <a href="#">{text}</a>,
props: {
colSpan: 5,
},
};
},
}, {
title: 'Age',
dataIndex: 'age',
render: renderContent,
}, {
title: 'Home phone',
colSpan: 2,
dataIndex: 'tel',
render: (value, row, index) => {
const obj = {
children: value,
props: {},
};
if (index === 2) {
obj.props.rowSpan = 2;
}
// These two are merged into above cell
树形数据展示
表格支持树形数据的展示,可以通过设置 indentSize
以控制每一层的缩进宽度。
注:暂不支持父子数据递归关联选择。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
key: 'name',
}, {
title: 'Age',
dataIndex: 'age',
key: 'age',
width: '12%',
}, {
title: 'Address',
dataIndex: 'address',
width: '30%',
key: 'address',
}];
const data = [{
key: 1,
name: 'John Brown sr.',
age: 60,
address: 'New York No. 1 Lake Park',
children: [{
key: 11,
name: 'John Brown',
age: 42,
address: 'New York No. 2 Lake Park',
}, {
key: 12,
name: 'John Brown jr.',
age: 30,
address: 'New York No. 3 Lake Park',
children: [{
key: 121,
name: 'Jimmy Brown',
age: 16,
address: 'New York No. 3 Lake Park',
}],
}, {
key: 13,
name: 'Jim Green sr.',
age: 72,
address: 'London No. 1 Lake Park',
children: [{
key: 131,
固定表头
方便一页内展示大量数据。
需要指定 column 的 width
属性,否则列头和内容可能不对齐。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
width: 150,
}, {
title: 'Age',
dataIndex: 'age',
width: 150,
}, {
title: 'Address',
dataIndex: 'address',
}];
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
});
}
ReactDOM.render(
<Table columns={columns} dataSource={data} pagination={{ pageSize: 50 }} scroll={{ y: 240 }} />,
document.getElementById('container'));
固定列
对于列数很多的数据,可以固定前后的列,横向滚动查看其它数据,需要和 scroll.x
配合使用。
若列头与内容不对齐或出现列重复,请指定列的宽度
width
。建议指定
scroll.x
为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过scroll.x
。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [
{ title: 'Full Name', width: 100, dataIndex: 'name', key: 'name', fixed: 'left' },
{ title: 'Age', width: 100, dataIndex: 'age', key: 'age', fixed: 'left' },
{ title: 'Column 1', dataIndex: 'address', key: '1' },
{ title: 'Column 2', dataIndex: 'address', key: '2' },
{ title: 'Column 3', dataIndex: 'address', key: '3' },
{ title: 'Column 4', dataIndex: 'address', key: '4' },
{ title: 'Column 5', dataIndex: 'address', key: '5' },
{ title: 'Column 6', dataIndex: 'address', key: '6' },
{ title: 'Column 7', dataIndex: 'address', key: '7' },
{ title: 'Column 8', dataIndex: 'address', key: '8' },
{
title: 'Action',
key: 'operation',
fixed: 'right',
width: 100,
render: () => <a href="#">action</a>,
},
];
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York Park',
}, {
key: '2',
name: 'Jim Green',
age: 40,
address: 'London Park',
}];
ReactDOM.render(<Table columns={columns} dataSource={data} scroll={{ x: 1300 }} />, document.getElementById('container'));
固定头和列
适合同时展示有大量数据和数据列。
若列头与内容不对齐或出现列重复,请指定列的宽度
width
。建议指定
scroll.x
为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过scroll.x
。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [
{ title: 'Full Name', width: 100, dataIndex: 'name', key: 'name', fixed: 'left' },
{ title: 'Age', width: 100, dataIndex: 'age', key: 'age', fixed: 'left' },
{ title: 'Column 1', dataIndex: 'address', key: '1', width: 150 },
{ title: 'Column 2', dataIndex: 'address', key: '2', width: 150 },
{ title: 'Column 3', dataIndex: 'address', key: '3', width: 150 },
{ title: 'Column 4', dataIndex: 'address', key: '4', width: 150 },
{ title: 'Column 5', dataIndex: 'address', key: '5', width: 150 },
{ title: 'Column 6', dataIndex: 'address', key: '6', width: 150 },
{ title: 'Column 7', dataIndex: 'address', key: '7', width: 150 },
{ title: 'Column 8', dataIndex: 'address', key: '8' },
{
title: 'Action',
key: 'operation',
fixed: 'right',
width: 100,
render: () => <a href="#">action</a>,
},
];
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
key: i,
name: `Edrward ${i}`,
age: 32,
address: `London Park no. ${i}`,
});
}
ReactDOM.render(<Table columns={columns} dataSource={data} scroll={{ x: 1500, y: 300 }} />, document.getElementById('container'));
表头分组
columns[n]
可以内嵌 children
,以渲染分组表头。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
const columns = [{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: 100,
fixed: 'left',
filters: [{
text: 'Joe',
value: 'Joe',
}, {
text: 'John',
value: 'John',
}],
onFilter: (value, record) => record.name.indexOf(value) === 0,
}, {
title: 'Other',
children: [{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: 200,
sorter: (a, b) => a.age - b.age,
}, {
title: 'Address',
children: [{
title: 'Street',
dataIndex: 'street',
key: 'street',
width: 200,
}, {
title: 'Block',
children: [{
title: 'Building',
dataIndex: 'building',
key: 'building',
width: 100,
}, {
title: 'Door No.',
dataIndex: 'number',
key: 'number',
width: 100,
}],
}],
}],
可编辑单元格
带单元格编辑功能的表格。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Input, Icon, Button, Popconfirm } from 'choerodon-ui';
class EditableCell extends React.Component {
state = {
value: this.props.value,
editable: false,
}
handleChange = (e) => {
const value = e.target.value;
this.setState({ value });
}
check = () => {
this.setState({ editable: false });
if (this.props.onChange) {
this.props.onChange(this.state.value);
}
}
edit = () => {
this.setState({ editable: true });
}
render() {
const { value, editable } = this.state;
return (
<div className="editable-cell">
{
editable ? (
<div className="editable-cell-input-wrapper">
<Input
value={value}
onChange={this.handleChange}
onPressEnter={this.check}
/>
<Icon
type="check"
className="editable-cell-icon-check"
onClick={this.check}
/>
</div>
) : (
<div className="editable-cell-text-wrapper">
{value || ' '}
<Icon
可编辑行
带行编辑功能的表格。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Input, Popconfirm } from 'choerodon-ui';
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
key: i.toString(),
name: `Edrward ${i}`,
age: 32,
address: `London Park no. ${i}`,
});
}
const EditableCell = ({ editable, value, onChange }) => (
<div>
{editable
? <Input style={{ margin: '-5px 0' }} value={value} onChange={e => onChange(e.target.value)} />
: value
}
</div>
);
class EditableTable extends React.Component {
constructor(props) {
super(props);
this.columns = [{
title: 'name',
dataIndex: 'name',
width: '25%',
render: (text, record) => this.renderColumns(text, record, 'name'),
}, {
title: 'age',
dataIndex: 'age',
width: '15%',
render: (text, record) => this.renderColumns(text, record, 'age'),
}, {
title: 'address',
dataIndex: 'address',
width: '40%',
render: (text, record) => this.renderColumns(text, record, 'address'),
}, {
title: 'operation',
dataIndex: 'operation',
render: (text, record) => {
const { editable } = record;
return (
<div className="editable-row-operations">
{
嵌套子表格
展示每行数据更详细的信息。
import React from 'react';
import ReactDOM from 'react-dom';
import { Table, Badge, Menu, Dropdown, Icon } from 'choerodon-ui';
const menu = (
<Menu>
<Menu.Item>
Action 1
</Menu.Item>
<Menu.Item>
Action 2
</Menu.Item>
</Menu>
);
function NestedTable() {
const expandedRowRender = () => {
const columns = [
{ title: 'Date', dataIndex: 'date', key: 'date' },
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Status', key: 'state', render: () => <span><Badge status="success" />Finished</span> },
{ title: 'Upgrade Status', dataIndex: 'upgradeNum', key: 'upgradeNum' },
{
title: 'Action',
dataIndex: 'operation',
key: 'operation',
render: () => (
<span className="table-operation">
<a href="#">Pause</a>
<a href="#">Stop</a>
<Dropdown overlay={menu}>
<a href="#">
More <Icon type="down" />
</a>
</Dropdown>
</span>
),
},
];
const data = [];
for (let i = 0; i < 3; ++i) {
data.push({
key: i,
date: '2014-12-24 23:12:00',
name: 'This is production name',
upgradeNum: 'Upgraded: 56',
拖拽排序
使用自定义元素,我们可以集成 react-dnd 来实现拖拽排序。
import React, { useState, useCallback, useRef } from 'react';
import ReactDOM from 'react-dom';
import { Table } from 'choerodon-ui';
import { DndProvider, useDrag, useDrop, createDndContext } from 'react-dnd';
import update from 'immutability-helper';
// import { HTML5Backend } from 'react-dnd-html5-backend';
const RNDContext = createDndContext(HTML5Backend);
const type = 'DragableBodyRow';
const DragableBodyRow = ({
index,
moveRow,
className,
style,
...restProps
}) => {
const ref = React.useRef();
const [{ isOver, dropClassName }, drop] = useDrop({
accept: type,
collect: (monitor) => {
const { index: dragIndex } = monitor.getItem() || {};
if (dragIndex === index) {
return {};
}
return {
isOver: monitor.isOver(),
dropClassName:
dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
};
},
drop: (item) => {
moveRow(item.index, index);
},
});
const [, drag] = useDrag({
item: { type, index },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
drop(drag(ref));
return (
<tr
ref={ref}
className={`${className}${isOver ? dropClassName : ''}`}
导出表单
展示一个表单的导出操作
import ReactDOM from 'react-dom';
import { Table, Button, Icon, Divider } from 'choerodon-ui';
import React, { useState } from 'react';
import axios from 'axios';
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name1',
render: (text) => <a href="#">{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age1',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address1',
},
{
title: '',
key: 'action1',
render: (text, record) => (
<span>
<a href="#">Action 一 {record.name}</a>
<Divider type="vertical" />
<a href="#">Delete</a>
<Divider type="vertical" />
<a href="#" className="c7n-dropdown-link">
More actions <Icon type="down" />
</a>
</span>
),
},
];
const data = [
{
key: '11',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '12',
API
Table
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
autoScroll | 是否在翻页时自动滚动到表格可视区域,并滚动到第一条 | boolean | true |
bordered | 是否展示外边框和列边框 | boolean | false |
columns | 表格列的配置描述,具体项见下表 | ColumnProps[] | - |
components | 覆盖默认的 table 元素 | object | - |
dataSource | 数据数组 | any[] | |
defaultExpandAllRows | 初始时,是否展开所有行 | boolean | false |
defaultExpandedRowKeys | 默认展开的行 | string[] | - |
expandedRowKeys | 展开的行,控制属性 | string[] | - |
expandedRowRender | 额外的展开行 | Function(record):ReactNode | - |
expandRowByClick | 通过点击行来展开子行 | boolean | false |
footer | 表格尾部 | Function(currentPageData) | |
empty | 当数据源为空时显示的内容 | ReactNode | - |
indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 |
loading | 页面是否加载中 | boolean|object | false |
locale | 默认文案设置,目前包括排序、过滤、空数据文案 | object | filterConfirm: ‘确定’ filterReset: ‘重置’ emptyText: ‘暂无数据’ |
pagination | 分页器,参考配置项或 pagination,设为 false 时不展示和进行分页 | object | |
rowClassName | 表格行的类名 | Function(record, index):string | - |
rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string|Function(record):string | ‘key’ |
rowSelection | 列表项是否可选择,配置项 | object | null |
scroll | 设置横向或纵向滚动,也可用于指定滚动区域的宽和高,建议为 x 设置一个数字,如果要设置为 true ,需要配合样式 .c7n-table td { white-space: nowrap; } | { x: number | true, y: number } | - |
showHeader | 是否显示表头 | boolean | true |
size | 正常或迷你类型,default or small | string | default |
title | 表格标题 | Function(currentPageData) | |
onChange | 分页、排序、筛选变化时触发 | Function(pagination, filters, sorter) | |
onColumnFilterChange | 右上角行过滤按钮中选项变化时触发 | Function(item) | |
onExpand | 点击展开图标时触发 | Function(expanded, record) | |
onExpandedRowsChange | 展开的行变化时触发 | Function(expandedRows) | |
onHeaderRow | 设置头部行属性 | Function(column, index) | - |
onRow | 设置行属性 | Function(record, index) | - |
filterBar | 显示过滤条,设置为false时,在列头上会显示过滤菜单按钮 | boolean | true |
filters | <受控>过滤条中的过滤条件,例:[{ name: ‘Jom’ }, ‘OR’, { name: ‘Jim’ }] ,name 为列的 key 或 dataIndex | any[] | - |
noFilters | 去掉组件自带的模糊搜索 | boolean | false |
filterBarPlaceholder | 过滤条的占位文本 | string |
onRow 用法
适用于 onRow
onHeaderRow
onCell
onHeaderCell
。
<Table
onRow={(record) => {
return {
onClick: () => {}, // 点击行
onMouseEnter: () => {}, // 鼠标移入行
onXxxx...
};
}}
onHeaderRow={(column) => {
return {
onClick: () => {}, // 点击表头行
};
}}
/>
Column
列描述数据对象,是 columns 中的一项,Column 使用相同的 API。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
className | 列的 className | string | - |
colSpan | 表头列合并,设置为 0 时,不渲染 | number | |
dataIndex | 列数据在数据项中对应的 key,支持 a.b.c 的嵌套写法 | string | - |
disableClick | 禁用点击列表筛选项 | boolean | false |
filterDropdown | 可以自定义筛选菜单,此函数只负责渲染图层,需要自行编写各种交互 | ReactNode | - |
filterDropdownVisible | 用于控制自定义筛选菜单是否可见 | boolean | - |
filtered | 标识数据是否经过过滤,筛选图标会高亮 | boolean | false |
filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | string[] | - |
filterIcon | 自定义 fiter 图标。 | ReactNode | false |
filterMultiple | 是否多选 | boolean | false |
filters | 表头的筛选菜单项 | object[] | - |
fixed | 列是否固定,可选 true (等效于 left) ‘left’ ‘right’ | boolean|string | false |
key | React 需要的 key,如果已经设置了唯一的 dataIndex ,可以忽略这个属性 | string | - |
render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return里面可以设置表格行/列合并 | Function(text, record, index) {} | - |
align | 设置列内容的对齐方式 | ‘left’ | ‘right’ | ‘center’ | ‘left’ |
sorter | 排序函数,本地排序使用一个函数(参考 Array.sort 的 compareFunction),需要服务端排序可设为 true | Function|boolean | - |
sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 ‘ascend’ ‘descend’ false | boolean|string | - |
title | 列头显示文字 | string|ReactNode | - |
filterTitle | 过滤条可选则的列的名字,默认为属性title 的值 | string|ReactNode | - |
width | 列宽度 | string|number | - |
onCell | 设置单元格属性 | Function(record) | - |
onFilter | 本地模式下,确定筛选的运行函数 | Function | - |
onFilterDropdownVisibleChange | 自定义筛选菜单可见变化时调用 | function(visible) {} | - |
onHeaderCell | 设置头部单元格属性 | Function(column) | - |
ColumnGroup
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
title | 列头显示文字 | string|ReactNode | - |
pagination
分页的配置项。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
position | 指定分页显示的位置 | ‘top’ | ‘bottom’ | ‘both’ | ‘bottom’ |
更多配置项,请查看 Pagination
。
rowSelection
选择功能的配置。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
fixed | 把选择框列固定在左边 | boolean | - |
getCheckboxProps | 选择框的默认属性配置 | Function(record) | - |
hideDefaultSelections | 去掉『全选』『反选』两个默认选项 | boolean | false |
selectedRowKeys | 指定选中项的 key 数组,需要和 onChange 进行配合 | string[] | [] |
columnWidth | 自定义列表选择框宽度 | string|number | - |
selections | 自定义选择项 配置项, 设为 true 时使用默认选择项 | object[]|boolean | true |
type | 多选/单选,checkbox or radio | string | checkbox |
onChange | 选中项发生变化的时的回调 | Function(selectedRowKeys, selectedRows) | - |
onSelect | 用户手动选择/取消选择某列的回调 | Function(record, selected, selectedRows, nativeEvent) | - |
onSelectAll | 用户手动选择/取消选择所有列的回调 | Function(selected, selectedRows, changeRows) | - |
onSelectInvert | 用户手动选择反选的回调 | Function(selectedRows) | - |
selection
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
key | React 需要的 key,建议设置 | string | - |
text | 选择项显示的文字 | string|React.ReactNode | - |
onSelect | 选择项点击回调 | Function(changeableRowKeys) | - |
在 TypeScript 中使用
import { Table } from 'choerodon-ui';
import { ColumnProps } from 'choerodon-ui/lib/table';
interface IUser {
key: number;
name: string;
}
const columns: ColumnProps<IUser>[] = [{
key: 'name',
title: 'Name',
dataIndex: 'name',
}];
const data: IUser[] = [{
key: 0,
name: 'Jack',
}];
class UserTable extends Table<IUser> {}
<UserTable columns={columns} dataSource={data} />
// 使用 JSX 风格的 API
class NameColumn extends Table.Column<IUser> {}
<UserTable dataSource={data}>
<NameColumn key="name" title="Name" dataIndex="name" />
</UserTable>
注意
按照 React 的规范,所有的组件数组必须绑定 key。在 Table 中,dataSource
和 columns
里的数据值都需要指定 key
值。对于 dataSource
默认将每列数据的 key
属性作为唯一的标识。
如果你的数据没有这个属性,务必使用 rowKey
来指定数据列的主键。若没有指定,控制台会出现以下的提示,表格组件也会出现各类奇怪的错误。
// 比如你的数据主键是 uid
return <Table rowKey="uid" />;
// 或
return <Table rowKey={record => record.uid} />;