一、基本使用

一个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组件属性中的坑及常用方法总结

  1. 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>
      ),
    },
  ];