一、基本使用
一个Table表格主要由表头和表格内容(即数据)组成,所以最基本的Table就是由column、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} />
上述列子来源于官网:ant-design之table组件
当然,实际需求中的表格多种多样,有的是动态生成表头及内容的,有的是可编辑表格的,有的是层级结构的等等,这些复杂的表格操作原型都在官网有所体现,剩下的就是灵活运用了。下面就说说自己在项目实际使用的一些坑。
二、Table组件属性中的坑及常用方法总结
- rowSelection方法
<Table/> 组件中有 rowSelection={rowSelection} 方法,可以让Table的第一列成为联动的选择框。
坑:API中表示通过 rowSelection.selectedRowKeys 来控制选中项,但selectedRowKeys 控制的只是dataSource当前的顺序编号。所以在table有分页的时候,可能会导致选择的明明是第一页,但其他几页也都处于选中状态,且如果选择的是第n页第m行,但实际选的内容也只是第一页的第m行。
解决方案:加上rowKey="id"或者rowKey={record => record.id}。(注:id表示dataSource数组中每一组的某个值)
// 代码展示
<Table rowSelection={rowSelection} columns={columns} dataSource={data} rowKey={record => record.id} />
2.pagination方法
不设置时候,默认十条每页。
写分页的时候,搭配onChange方法来实现数据的改变
// 代码展示
handleTableChange = (pagination) => {
const { onChange } = this.props;
if (onChange) {
onChange(pagination); // 在model层改变当前页,传给后台更新当前页数据,即list和pagination,
}
};
const colums = [{...], {...},{....},...]
const list = [......],
const paginationProps = {
current: 1,
pageSize: 10,
total: 100,
totalPage: 10,
}
<Table
columns={columns}
dataSource={list}
bordered
pagination={paginationProps}
onChange={this.handleTableChange}
/>
3.columns方法
(1)序号列:常需要知道表格多少行一共,在实际业务可表示为多少件商品、多少个订单等,所以有一列为’序号‘来计数。实际后台返回的dataSource里面没有这个字段,表头有这一列,那就需要前端来处理。
// 代码展示
const columns = [
{
title: '序号',
dataIndex: 'number',
key: 'number',
},
{
title: '某某值',
dataIndex: 'stringValue',
key: 'stringValue',
},
];
const { data } = this.props // data为表格数据,后台请求而来
// data格式 data = [{id: 'xxx', stringValue: 'aaa' }]
data.length > 0 && data.map(item => (item.number = number++)); // 处理data
<Table dataSource={data} columns={columns} bordered />
(2). 关于多个值用逗号隔开展示及超长处理:业务里会碰到每行的某一列下面的这个值可能是个数组,要拿个这个数组里的某个属性用逗号隔开展示出来。而且有时候非常长,可以限制一下多长就用省略号,另外可以用Popover鼠标滑过提示一下这一格显示的内容,比较友好。
// 代码实现
const columns = [
{
title: '名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '已关联xx名称',
dataIndex: 'xxname',
key: 'xxname',
align: 'center',
render: val => {
const sxm = val.map(item => {
if (val[val.length - 1] === item) {
return `${item.name}`;
}
return `${item.name},`;
});
return (
<Popover content={sxm}>
<span className={styles.colSql}>{sxm}</span>
</Popover>
);
},
},
{
title: '操作',
align: 'center',
render: (text, record) => (
<Fragment>
<a onClick={() => this.handleCheckInfo(record)}>编辑</a>
<Divider type="vertical" />
<Popconfirm title="确定删除该品类?" onConfirm={() =>this.handleDelete(record)}>
<a>删除</a>
</Popconfirm>
</Fragment>
),
},
];
<Table data={data} columns={this.columns} />
// 样式补充
.colSql {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
width: 300px;
}
坑:和react搭配使用时,放在不同的位置,table取的方式也不同。
解决方案:放在定义组件内,render外使用要加this,即columns={this.columns}。放在定义组件外为全局环境,定义在render内,都不用加this。放在render内的一个好处是,可以随时获取model和state的数据变化。
(3).关于table表格内显示图片,且可以放大查看图片的操作
// 代码展示
state = {
previewVisible: false,
previewImage: '',
}
handleCancel = () => {
this.setState({
previewVisible: false,
});
};
handlePreViewVisible = val => {
this.setState({
previewVisible: true,
previewImage: val,
});
};
columns = [
{
title: '名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '图片',
dataIndex: 'logoUrl',
key: 'logoUrl',
align: 'center',
render: val => {
const { previewVisible, previewImage } = this.state;
if (val) {
return (
<div className="clearfix">
<img
style={{ width: 60, height: 60 }}
src={val}
onClick={() => this.handlePreViewVisible(val)}
alt="品牌logo"
/>
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
</div>
);
}
return '';
},
},
{
title: '操作',
align: 'center',
width: '15%',
dataIndex: 'operation',
key: 'operation',
render: (text, record) => (
<Fragment>
<a onClick={() => this.handleUpdateModalVisible(true, record)}>编辑</a>
<Divider type="vertical" />
<Popconfirm title="是否要删除此行?" onConfirm={() => this.handleDelete(record.id)}>
<a>删除</a>
</Popconfirm>
</Fragment>
),
},
];