Table 表格

展示行列数据。

何时使用

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

如何使用

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

代码演示

Table 表格 - 图1

远程加载数据

这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。另外,本例也展示了筛选排序功能如何交给服务端实现,列不需要指定具体的 onFiltersorter 函数,而是在把筛选和排序的参数发到服务端来处理。注意,此示例使用 模拟接口,展示数据可能不准确,请打开网络面板查看请求。

  1. <template>
  2. <a-table
  3. :columns="columns"
  4. :rowKey="record => record.login.uuid"
  5. :dataSource="data"
  6. :pagination="pagination"
  7. :loading="loading"
  8. @change="handleTableChange"
  9. >
  10. <template slot="name" slot-scope="name">
  11. {{name.first}} {{name.last}}
  12. </template>
  13. </a-table>
  14. </template>
  15. <script>
  16. import reqwest from 'reqwest';
  17. const columns = [
  18. {
  19. title: 'Name',
  20. dataIndex: 'name',
  21. sorter: true,
  22. width: '20%',
  23. scopedSlots: { customRender: 'name' },
  24. },
  25. {
  26. title: 'Gender',
  27. dataIndex: 'gender',
  28. filters: [{ text: 'Male', value: 'male' }, { text: 'Female', value: 'female' }],
  29. width: '20%',
  30. },
  31. {
  32. title: 'Email',
  33. dataIndex: 'email',
  34. },
  35. ];
  36. export default {
  37. mounted() {
  38. this.fetch();
  39. },
  40. data() {
  41. return {
  42. data: [],
  43. pagination: {},
  44. loading: false,
  45. columns,
  46. };
  47. },
  48. methods: {
  49. handleTableChange(pagination, filters, sorter) {
  50. console.log(pagination);
  51. const pager = { ...this.pagination };
  52. pager.current = pagination.current;
  53. this.pagination = pager;
  54. this.fetch({
  55. results: pagination.pageSize,
  56. page: pagination.current,
  57. sortField: sorter.field,
  58. sortOrder: sorter.order,
  59. ...filters,
  60. });
  61. },
  62. fetch(params = {}) {
  63. console.log('params:', params);
  64. this.loading = true;
  65. reqwest({
  66. url: 'https://randomuser.me/api',
  67. method: 'get',
  68. data: {
  69. results: 10,
  70. ...params,
  71. },
  72. type: 'json',
  73. }).then(data => {
  74. const pagination = { ...this.pagination };
  75. // Read total count from server
  76. // pagination.total = data.totalCount;
  77. pagination.total = 200;
  78. this.loading = false;
  79. this.data = data.results;
  80. this.pagination = pagination;
  81. });
  82. },
  83. },
  84. };
  85. </script>

Table 表格 - 图2

基本用法

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

  1. <template>
  2. <a-table :columns="columns" :dataSource="data">
  3. <a slot="name" slot-scope="text" href="javascript:;">{{text}}</a>
  4. <span slot="customTitle"><a-icon type="smile-o" /> Name</span>
  5. <span slot="tags" slot-scope="tags">
  6. <a-tag
  7. v-for="tag in tags"
  8. :color="tag==='loser' ? 'volcano' : (tag.length > 5 ? 'geekblue' : 'green')"
  9. :key="tag"
  10. >
  11. {{tag.toUpperCase()}}
  12. </a-tag>
  13. </span>
  14. <span slot="action" slot-scope="text, record">
  15. <a href="javascript:;">Invite 一 {{record.name}}</a>
  16. <a-divider type="vertical" />
  17. <a href="javascript:;">Delete</a>
  18. <a-divider type="vertical" />
  19. <a href="javascript:;" class="ant-dropdown-link"> More actions <a-icon type="down" /> </a>
  20. </span>
  21. </a-table>
  22. </template>
  23. <script>
  24. const columns = [
  25. {
  26. dataIndex: 'name',
  27. key: 'name',
  28. slots: { title: 'customTitle' },
  29. scopedSlots: { customRender: 'name' },
  30. },
  31. {
  32. title: 'Age',
  33. dataIndex: 'age',
  34. key: 'age',
  35. },
  36. {
  37. title: 'Address',
  38. dataIndex: 'address',
  39. key: 'address',
  40. },
  41. {
  42. title: 'Tags',
  43. key: 'tags',
  44. dataIndex: 'tags',
  45. scopedSlots: { customRender: 'tags' },
  46. },
  47. {
  48. title: 'Action',
  49. key: 'action',
  50. scopedSlots: { customRender: 'action' },
  51. },
  52. ];
  53. const data = [
  54. {
  55. key: '1',
  56. name: 'John Brown',
  57. age: 32,
  58. address: 'New York No. 1 Lake Park',
  59. tags: ['nice', 'developer'],
  60. },
  61. {
  62. key: '2',
  63. name: 'Jim Green',
  64. age: 42,
  65. address: 'London No. 1 Lake Park',
  66. tags: ['loser'],
  67. },
  68. {
  69. key: '3',
  70. name: 'Joe Black',
  71. age: 32,
  72. address: 'Sidney No. 1 Lake Park',
  73. tags: ['cool', 'teacher'],
  74. },
  75. ];
  76. export default {
  77. data() {
  78. return {
  79. data,
  80. columns,
  81. };
  82. },
  83. };
  84. </script>

Table 表格 - 图3

带边框

添加表格边框线,页头和页脚。

<template>
  <a-table :columns="columns" :dataSource="data" bordered>
    <template slot="name" slot-scope="text">
      <a href="javascript:;">{{text}}</a>
    </template>
    <template slot="title" slot-scope="currentPageData">
      Header
    </template>
    <template slot="footer" slot-scope="currentPageData">
      Footer
    </template>
  </a-table>
</template>
<script>
  const columns = [
    {
      title: 'Name',
      dataIndex: 'name',
      scopedSlots: { customRender: 'name' },
    },
    {
      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',
    },
  ];

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>
<style>
  th.column-money,
  td.column-money {
    text-align: right !important;
  }
</style>

Table 表格 - 图4

表格行/列合并

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

<template>
  <a-table :columns="columns" :dataSource="data" bordered>
    <template slot="name" slot-scope="text">
      <a href="javascript:;">{{text}}</a>
    </template>
  </a-table>
</template>
<script>
  // 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,
      attrs: {},
    };
    if (index === 4) {
      obj.attrs.colSpan = 0;
    }
    return obj;
  };

  const data = [
    {
      key: '1',
      name: 'John Brown',
      age: 32,
      tel: '0571-22098909',
      phone: 18889898989,
      address: 'New York No. 1 Lake Park',
    },
    {
      key: '2',
      name: 'Jim Green',
      tel: '0571-22098333',
      phone: 18889898888,
      age: 42,
      address: 'London No. 1 Lake Park',
    },
    {
      key: '3',
      name: 'Joe Black',
      age: 32,
      tel: '0575-22098909',
      phone: 18900010002,
      address: 'Sidney No. 1 Lake Park',
    },
    {
      key: '4',
      name: 'Jim Red',
      age: 18,
      tel: '0575-22098909',
      phone: 18900010002,
      address: 'London No. 2 Lake Park',
    },
    {
      key: '5',
      name: 'Jake White',
      age: 18,
      tel: '0575-22098909',
      phone: 18900010002,
      address: 'Dublin No. 2 Lake Park',
    },
  ];

  export default {
    data() {
      const columns = [
        {
          title: 'Name',
          dataIndex: 'name',
          customRender: (text, row, index) => {
            if (index < 4) {
              return <a href="javascript:;">{text}</a>;
            }
            return {
              children: <a href="javascript:;">{text}</a>,
              attrs: {
                colSpan: 5,
              },
            };
          },
        },
        {
          title: 'Age',
          dataIndex: 'age',
          customRender: renderContent,
        },
        {
          title: 'Home phone',
          colSpan: 2,
          dataIndex: 'tel',
          customRender: (value, row, index) => {
            const obj = {
              children: value,
              attrs: {},
            };
            if (index === 2) {
              obj.attrs.rowSpan = 2;
            }
            // These two are merged into above cell
            if (index === 3) {
              obj.attrs.rowSpan = 0;
            }
            if (index === 4) {
              obj.attrs.colSpan = 0;
            }
            return obj;
          },
        },
        {
          title: 'Phone',
          colSpan: 0,
          dataIndex: 'phone',
          customRender: renderContent,
        },
        {
          title: 'Address',
          dataIndex: 'address',
          customRender: renderContent,
        },
      ];
      return {
        data,
        columns,
      };
    },
  };
</script>

Table 表格 - 图5

自定义筛选菜单

通过 filterDropdown 定义自定义的列筛选功能,并实现一个搜索列的示例。

<template>
  <a-table :dataSource="data" :columns="columns">
    <div
      slot="filterDropdown"
      slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }"
      style="padding: 8px"
    >
      <a-input
        v-ant-ref="c => searchInput = c"
        :placeholder="`Search ${column.dataIndex}`"
        :value="selectedKeys[0]"
        @change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
        @pressEnter="() => handleSearch(selectedKeys, confirm)"
        style="width: 188px; margin-bottom: 8px; display: block;"
      />
      <a-button
        type="primary"
        @click="() => handleSearch(selectedKeys, confirm)"
        icon="search"
        size="small"
        style="width: 90px; margin-right: 8px"
        >Search</a-button
      >
      <a-button @click="() => handleReset(clearFilters)" size="small" style="width: 90px"
        >Reset</a-button
      >
    </div>
    <a-icon
      slot="filterIcon"
      slot-scope="filtered"
      type="search"
      :style="{ color: filtered ? '#108ee9' : undefined }"
    />
    <template slot="customRender" slot-scope="text">
      <span v-if="searchText">
        <template
          v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))"
        >
          <mark
            v-if="fragment.toLowerCase() === searchText.toLowerCase()"
            :key="i"
            class="highlight"
            >{{fragment}}</mark
          >
          <template v-else
            >{{fragment}}</template
          >
        </template>
      </span>
      <template v-else
        >{{text}}</template
      >
    </template>
  </a-table>
</template>

<script>
  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',
    },
  ];

  export default {
    data() {
      return {
        data,
        searchText: '',
        searchInput: null,
        columns: [
          {
            title: 'Name',
            dataIndex: 'name',
            key: 'name',
            scopedSlots: {
              filterDropdown: 'filterDropdown',
              filterIcon: 'filterIcon',
              customRender: 'customRender',
            },
            onFilter: (value, record) => record.name.toString().toLowerCase().includes(value.toLowerCase()),
            onFilterDropdownVisibleChange: visible => {
              if (visible) {
                setTimeout(() => {
                  this.searchInput.focus();
                }, 0);
              }
            },
          },
          {
            title: 'Age',
            dataIndex: 'age',
            key: 'age',
            scopedSlots: {
              filterDropdown: 'filterDropdown',
              filterIcon: 'filterIcon',
              customRender: 'customRender',
            },
            onFilter: (value, record) => record.age.toString().toLowerCase().includes(value.toLowerCase()),
            onFilterDropdownVisibleChange: visible => {
              if (visible) {
                setTimeout(() => {
                  this.searchInput.focus();
                });
              }
            },
          },
          {
            title: 'Address',
            dataIndex: 'address',
            key: 'address',
            scopedSlots: {
              filterDropdown: 'filterDropdown',
              filterIcon: 'filterIcon',
              customRender: 'customRender',
            },
            onFilter: (value, record) => record.address.toString().toLowerCase().includes(value.toLowerCase()),
            onFilterDropdownVisibleChange: visible => {
              if (visible) {
                setTimeout(() => {
                  this.searchInput.focus();
                });
              }
            },
          },
        ],
      };
    },
    methods: {
      handleSearch(selectedKeys, confirm) {
        confirm();
        this.searchText = selectedKeys[0];
      },

      handleReset(clearFilters) {
        clearFilters();
        this.searchText = '';
      },
    },
  };
</script>
<style scoped>
  .highlight {
    background-color: rgb(255, 192, 105);
    padding: 0px;
  }
</style>

Table 表格 - 图6

可编辑单元格

带单元格编辑功能的表格。

<template>
  <div>
    <a-button class="editable-add-btn" @click="handleAdd">Add</a-button>
    <a-table bordered :dataSource="dataSource" :columns="columns">
      <template slot="name" slot-scope="text, record">
        <editable-cell :text="text" @change="onCellChange(record.key, 'name', $event)" />
      </template>
      <template slot="operation" slot-scope="text, record">
        <a-popconfirm
          v-if="dataSource.length"
          title="Sure to delete?"
          @confirm="() => onDelete(record.key)"
        >
          <a href="javascript:;">Delete</a>
        </a-popconfirm>
      </template>
    </a-table>
  </div>
</template>
<script>
  import EditableCell from './EditableCell';
  /*
   * EditableCell Code https://github.com/vueComponent/ant-design-vue/blob/master/components/table/demo/EditableCell.vue
   */
  export default {
    components: {
      EditableCell,
    },
    data() {
      return {
        dataSource: [
          {
            key: '0',
            name: 'Edward King 0',
            age: '32',
            address: 'London, Park Lane no. 0',
          },
          {
            key: '1',
            name: 'Edward King 1',
            age: '32',
            address: 'London, Park Lane no. 1',
          },
        ],
        count: 2,
        columns: [
          {
            title: 'name',
            dataIndex: 'name',
            width: '30%',
            scopedSlots: { customRender: 'name' },
          },
          {
            title: 'age',
            dataIndex: 'age',
          },
          {
            title: 'address',
            dataIndex: 'address',
          },
          {
            title: 'operation',
            dataIndex: 'operation',
            scopedSlots: { customRender: 'operation' },
          },
        ],
      };
    },
    methods: {
      onCellChange(key, dataIndex, value) {
        const dataSource = [...this.dataSource];
        const target = dataSource.find(item => item.key === key);
        if (target) {
          target[dataIndex] = value;
          this.dataSource = dataSource;
        }
      },
      onDelete(key) {
        const dataSource = [...this.dataSource];
        this.dataSource = dataSource.filter(item => item.key !== key);
      },
      handleAdd() {
        const { count, dataSource } = this;
        const newData = {
          key: count,
          name: `Edward King ${count}`,
          age: 32,
          address: `London, Park Lane no. ${count}`,
        };
        this.dataSource = [...dataSource, newData];
        this.count = count + 1;
      },
    },
  };
</script>
<style>
  .editable-cell {
    position: relative;
  }

  .editable-cell-input-wrapper,
  .editable-cell-text-wrapper {
    padding-right: 24px;
  }

  .editable-cell-text-wrapper {
    padding: 5px 24px 5px 5px;
  }

  .editable-cell-icon,
  .editable-cell-icon-check {
    position: absolute;
    right: 0;
    width: 20px;
    cursor: pointer;
  }

  .editable-cell-icon {
    line-height: 18px;
    display: none;
  }

  .editable-cell-icon-check {
    line-height: 28px;
  }

  .editable-cell:hover .editable-cell-icon {
    display: inline-block;
  }

  .editable-cell-icon:hover,
  .editable-cell-icon-check:hover {
    color: #108ee9;
  }

  .editable-add-btn {
    margin-bottom: 8px;
  }
</style>

Table 表格 - 图7

可编辑行

带行编辑功能的表格。

<template>
  <a-table :columns="columns" :dataSource="data" bordered>
    <template
      v-for="col in ['name', 'age', 'address']"
      :slot="col"
      slot-scope="text, record, index"
    >
      <div :key="col">
        <a-input
          v-if="record.editable"
          style="margin: -5px 0"
          :value="text"
          @change="e => handleChange(e.target.value, record.key, col)"
        />
        <template v-else
          >{{text}}</template
        >
      </div>
    </template>
    <template slot="operation" slot-scope="text, record, index">
      <div class="editable-row-operations">
        <span v-if="record.editable">
          <a @click="() => save(record.key)">Save</a>
          <a-popconfirm title="Sure to cancel?" @confirm="() => cancel(record.key)">
            <a>Cancel</a>
          </a-popconfirm>
        </span>
        <span v-else>
          <a @click="() => edit(record.key)">Edit</a>
        </span>
      </div>
    </template>
  </a-table>
</template>
<script>
  const columns = [
    {
      title: 'name',
      dataIndex: 'name',
      width: '25%',
      scopedSlots: { customRender: 'name' },
    },
    {
      title: 'age',
      dataIndex: 'age',
      width: '15%',
      scopedSlots: { customRender: 'age' },
    },
    {
      title: 'address',
      dataIndex: 'address',
      width: '40%',
      scopedSlots: { customRender: 'address' },
    },
    {
      title: 'operation',
      dataIndex: 'operation',
      scopedSlots: { customRender: 'operation' },
    },
  ];

  const data = [];
  for (let i = 0; i < 100; i++) {
    data.push({
      key: i.toString(),
      name: `Edrward ${i}`,
      age: 32,
      address: `London Park no. ${i}`,
    });
  }
  export default {
    data() {
      this.cacheData = data.map(item => ({ ...item }));
      return {
        data,
        columns,
      };
    },
    methods: {
      handleChange(value, key, column) {
        const newData = [...this.data];
        const target = newData.filter(item => key === item.key)[0];
        if (target) {
          target[column] = value;
          this.data = newData;
        }
      },
      edit(key) {
        const newData = [...this.data];
        const target = newData.filter(item => key === item.key)[0];
        if (target) {
          target.editable = true;
          this.data = newData;
        }
      },
      save(key) {
        const newData = [...this.data];
        const target = newData.filter(item => key === item.key)[0];
        if (target) {
          delete target.editable;
          this.data = newData;
          this.cacheData = newData.map(item => ({ ...item }));
        }
      },
      cancel(key) {
        const newData = [...this.data];
        const target = newData.filter(item => key === item.key)[0];
        if (target) {
          Object.assign(target, this.cacheData.filter(item => key === item.key)[0]);
          delete target.editable;
          this.data = newData;
        }
      },
    },
  };
</script>
<style scoped>
  .editable-row-operations a {
    margin-right: 8px;
  }
</style>

Table 表格 - 图8

树形数据展示

表格支持树形数据的展示,当数据中有 children 字段时会自动展示为树形表格,如果不需要或配置为其他字段可以用 childrenColumnName 进行配置。可以通过设置 indentSize 以控制每一层的缩进宽度。

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

<template>
  <a-table :columns="columns" :dataSource="data" :rowSelection="rowSelection" />
</template>
<script>
  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,
              name: 'Jim Green',
              age: 42,
              address: 'London No. 2 Lake Park',
              children: [
                {
                  key: 1311,
                  name: 'Jim Green jr.',
                  age: 25,
                  address: 'London No. 3 Lake Park',
                },
                {
                  key: 1312,
                  name: 'Jimmy Green sr.',
                  age: 18,
                  address: 'London No. 4 Lake Park',
                },
              ],
            },
          ],
        },
      ],
    },
    {
      key: 2,
      name: 'Joe Black',
      age: 32,
      address: 'Sidney No. 1 Lake Park',
    },
  ];

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

  export default {
    data() {
      return {
        data,
        columns,
        rowSelection,
      };
    },
  };
</script>

Table 表格 - 图9

可展开

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

<template>
  <a-table :columns="columns" :dataSource="data">
    <a slot="action" slot-scope="text" href="javascript:;">Delete</a>
    <p slot="expandedRowRender" slot-scope="record" style="margin: 0">{{record.description}}</p>
  </a-table>
</template>
<script>
  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', scopedSlots: { customRender: 'action' } },
  ];

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

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>

Table 表格 - 图10

固定头和列

适合同时展示有大量数据和数据列。

若列头与内容不对齐或出现列重复,请指定固定列的宽度 width。建议指定 scroll.x 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 scroll.x

<template>
  <a-table :columns="columns" :dataSource="data" :scroll="{ x: 1500, y: 300 }">
    <a slot="action" slot-scope="text" href="javascript:;">action</a>
  </a-table>
</template>
<script>
  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,
      scopedSlots: { customRender: 'action' },
    },
  ];

  const data = [];
  for (let i = 0; i < 100; i++) {
    data.push({
      key: i,
      name: `Edrward ${i}`,
      age: 32,
      address: `London Park no. ${i}`,
    });
  }

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>

Table 表格 - 图11

固定列

对于列数很多的数据,可以固定前后的列,横向滚动查看其它数据,需要和 scroll.x 配合使用。

若列头与内容不对齐或出现列重复,请指定固定列的宽度 width。建议指定 scroll.x 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 scroll.x

<template>
  <a-table :columns="columns" :dataSource="data" :scroll="{ x: 1300 }">
    <a slot="action" slot-scope="text" href="javascript:;">action</a>
  </a-table>
</template>
<script>
  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,
      scopedSlots: { customRender: 'action' },
    },
  ];

  const data = [
    {
      key: '1',
      name: 'John Brown',
      age: 32,
      address: 'New York Park',
    },
    {
      key: '2',
      name: 'Jim Green',
      age: 40,
      address: 'London Park',
    },
  ];

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>

Table 表格 - 图12

固定表头

方便一页内展示大量数据。需要指定 column 的 width 属性,否则列头和内容可能不对齐。(建议留一列不设宽度以适应弹性布局)

<template>
  <a-table
    :columns="columns"
    :dataSource="data"
    :pagination="{ pageSize: 50 }"
    :scroll="{ y: 240 }"
  />
</template>
<script>
  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}`,
    });
  }

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>

Table 表格 - 图13

表头分组

columns[n] 可以内嵌 children,以渲染分组表头。

<template>
  <a-table
    :columns="columns"
    :dataSource="data"
    bordered
    size="middle"
    :scroll="{ x: '130%', y: 240 }"
  />
</template>
<script>
  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,
                },
              ],
            },
          ],
        },
      ],
    },
    {
      title: 'Company',
      children: [
        {
          title: 'Company Address',
          dataIndex: 'companyAddress',
          key: 'companyAddress',
        },
        {
          title: 'Company Name',
          dataIndex: 'companyName',
          key: 'companyName',
        },
      ],
    },
    {
      title: 'Gender',
      dataIndex: 'gender',
      key: 'gender',
      width: 80,
      fixed: 'right',
    },
  ];

  const data = [];
  for (let i = 0; i < 100; i++) {
    data.push({
      key: i,
      name: 'John Brown',
      age: i + 1,
      street: 'Lake Park',
      building: 'C',
      number: 2035,
      companyAddress: 'Lake Street 42',
      companyName: 'SoftLake Co',
      gender: 'M',
    });
  }

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>

Table 表格 - 图14

筛选和排序

对某一列数据进行筛选,使用列的 filters 属性来指定需要筛选菜单的列,onFilter 用于筛选当前数据,filterMultiple 用于指定多选和单选。对某一列数据进行排序,通过指定列的 sorter 函数即可启动排序按钮。sorter: function(rowA, rowB) { … }, rowA、rowB 为比较的两个行数据。 sortDirections: ['ascend' | 'descend']改变每列可用的排序方式,切换排序时按数组内容依次切换,设置在table props上时对所有列生效。使用 defaultSortOrder 属性,设置列的默认排序顺序。

<template>
  <a-table :columns="columns" :dataSource="data" @change="onChange" />
</template>
<script>
  const columns = [
    {
      title: 'Name',
      dataIndex: 'name',
      filters: [
        {
          text: 'Joe',
          value: 'Joe',
        },
        {
          text: 'Jim',
          value: 'Jim',
        },
        {
          text: 'Submenu',
          value: 'Submenu',
          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) === 0,
      sorter: (a, b) => a.name.length - b.name.length,
      sortDirections: ['descend'],
    },
    {
      title: 'Age',
      dataIndex: 'age',
      sorter: (a, b) => a.age - b.age,
    },
    {
      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,
      sortDirections: ['descend', 'ascend'],
    },
  ];

  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 onChange(pagination, filters, sorter) {
    console.log('params', pagination, filters, sorter);
  }

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
    methods: {
      onChange,
    },
  };
</script>

Table 表格 - 图15

嵌套子表格

展示每行数据更详细的信息。

<template>
  <a-table :columns="columns" :dataSource="data" class="components-table-demo-nested">
    <a slot="operation" slot-scope="text" href="javascript:;">Publish</a>
    <a-table
      slot="expandedRowRender"
      slot-scope="text"
      :columns="innerColumns"
      :dataSource="innerData"
      :pagination="false"
    >
      <span slot="status" slot-scope="text"> <a-badge status="success" />Finished </span>
      <span slot="operation" slot-scope="text" class="table-operation">
        <a href="javascript:;">Pause</a>
        <a href="javascript:;">Stop</a>
        <a-dropdown>
          <a-menu slot="overlay">
            <a-menu-item>
              Action 1
            </a-menu-item>
            <a-menu-item>
              Action 2
            </a-menu-item>
          </a-menu>
          <a href="javascript:;"> More <a-icon type="down" /> </a>
        </a-dropdown>
      </span>
    </a-table>
  </a-table>
</template>
<script>
  const columns = [
    { title: 'Name', dataIndex: 'name', key: 'name' },
    { title: 'Platform', dataIndex: 'platform', key: 'platform' },
    { title: 'Version', dataIndex: 'version', key: 'version' },
    { title: 'Upgraded', dataIndex: 'upgradeNum', key: 'upgradeNum' },
    { title: 'Creator', dataIndex: 'creator', key: 'creator' },
    { title: 'Date', dataIndex: 'createdAt', key: 'createdAt' },
    { title: 'Action', key: 'operation', scopedSlots: { customRender: 'operation' } },
  ];

  const data = [];
  for (let i = 0; i < 3; ++i) {
    data.push({
      key: i,
      name: 'Screem',
      platform: 'iOS',
      version: '10.3.4.5654',
      upgradeNum: 500,
      creator: 'Jack',
      createdAt: '2014-12-24 23:12:00',
    });
  }

  const innerColumns = [
    { title: 'Date', dataIndex: 'date', key: 'date' },
    { title: 'Name', dataIndex: 'name', key: 'name' },
    { title: 'Status', key: 'state', scopedSlots: { customRender: 'status' } },
    { title: 'Upgrade Status', dataIndex: 'upgradeNum', key: 'upgradeNum' },
    {
      title: 'Action',
      dataIndex: 'operation',
      key: 'operation',
      scopedSlots: { customRender: 'operation' },
    },
  ];

  const innerData = [];
  for (let i = 0; i < 3; ++i) {
    innerData.push({
      key: i,
      date: '2014-12-24 23:12:00',
      name: 'This is production name',
      upgradeNum: 'Upgraded: 56',
    });
  }

  export default {
    data() {
      return {
        data,
        columns,
        innerColumns,
        innerData,
      };
    },
  };
</script>

Table 表格 - 图16

可控的筛选和排序

使用受控属性对筛选和排序状态进行控制。

  1. columns 中定义了 filteredValue 和 sortOrder 属性即视为受控模式。
  2. 只支持同时对一列进行排序,请保证只有一列的 sortOrder 属性是生效的。
  3. 务必指定 column.key
<template>
  <div>
    <div class="table-operations">
      <a-button @click="setAgeSort">Sort age</a-button>
      <a-button @click="clearFilters">Clear filters</a-button>
      <a-button @click="clearAll">Clear filters and sorters</a-button>
    </div>
    <a-table :columns="columns" :dataSource="data" @change="handleChange" />
  </div>
</template>
<script>
  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',
    },
  ];

  export default {
    data() {
      return {
        data,
        filteredInfo: null,
        sortedInfo: null,
      };
    },
    computed: {
      columns() {
        let { sortedInfo, filteredInfo } = this;
        sortedInfo = sortedInfo || {};
        filteredInfo = filteredInfo || {};
        const columns = [
          {
            title: 'Name',
            dataIndex: 'name',
            key: 'name',
            filters: [{ text: 'Joe', value: 'Joe' }, { text: 'Jim', value: 'Jim' }],
            filteredValue: filteredInfo.name || null,
            onFilter: (value, record) => record.name.includes(value),
            sorter: (a, b) => a.name.length - b.name.length,
            sortOrder: sortedInfo.columnKey === 'name' && sortedInfo.order,
          },
          {
            title: 'Age',
            dataIndex: 'age',
            key: 'age',
            sorter: (a, b) => a.age - b.age,
            sortOrder: sortedInfo.columnKey === 'age' && sortedInfo.order,
          },
          {
            title: 'Address',
            dataIndex: 'address',
            key: 'address',
            filters: [{ text: 'London', value: 'London' }, { text: 'New York', value: 'New York' }],
            filteredValue: filteredInfo.address || null,
            onFilter: (value, record) => record.address.includes(value),
            sorter: (a, b) => a.address.length - b.address.length,
            sortOrder: sortedInfo.columnKey === 'address' && sortedInfo.order,
          },
        ];
        return columns;
      },
    },
    methods: {
      handleChange(pagination, filters, sorter) {
        console.log('Various parameters', pagination, filters, sorter);
        this.filteredInfo = filters;
        this.sortedInfo = sorter;
      },
      clearFilters() {
        this.filteredInfo = null;
      },
      clearAll() {
        this.filteredInfo = null;
        this.sortedInfo = null;
      },
      setAgeSort() {
        this.sortedInfo = {
          order: 'descend',
          columnKey: 'age',
        };
      },
    },
  };
</script>
<style scoped>
  .table-operations {
    margin-bottom: 16px;
  }

  .table-operations > button {
    margin-right: 8px;
  }
</style>

Table 表格 - 图17

选择和操作

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

<template>
  <div>
    <div style="margin-bottom: 16px">
      <a-button type="primary" @click="start" :disabled="!hasSelected" :loading="loading">
        Reload
      </a-button>
      <span style="margin-left: 8px">
        <template v-if="hasSelected">
          {{`Selected ${selectedRowKeys.length} items`}}
        </template>
      </span>
    </div>
    <a-table
      :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
      :columns="columns"
      :dataSource="data"
    />
  </div>
</template>
<script>
  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}`,
    });
  }

  export default {
    data() {
      return {
        data,
        columns,
        selectedRowKeys: [], // Check here to configure the default column
        loading: false,
      };
    },
    computed: {
      hasSelected() {
        return this.selectedRowKeys.length > 0;
      },
    },
    methods: {
      start() {
        this.loading = true;
        // ajax request after empty completing
        setTimeout(() => {
          this.loading = false;
          this.selectedRowKeys = [];
        }, 1000);
      },
      onSelectChange(selectedRowKeys) {
        console.log('selectedRowKeys changed: ', selectedRowKeys);
        this.selectedRowKeys = selectedRowKeys;
      },
    },
  };
</script>

Table 表格 - 图18

自定义选择项

通过 rowSelection.selections 自定义选择项,默认不显示下拉选项,设为 true 时显示默认选择项。

<template>
  <a-table :rowSelection="rowSelection" :columns="columns" :dataSource="data" />
</template>
<script>
  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}`,
    });
  }

  export default {
    data() {
      return {
        data,
        columns,
        selectedRowKeys: [], // Check here to configure the default column
      };
    },
    computed: {
      rowSelection() {
        const { selectedRowKeys } = this;
        return {
          selectedRowKeys,
          onChange: this.onSelectChange,
          hideDefaultSelections: true,
          selections: [
            {
              key: 'all-data',
              text: 'Select All Data',
              onSelect: () => {
                this.selectedRowKeys = [...Array(46).keys()]; // 0...45
              },
            },
            {
              key: 'odd',
              text: 'Select Odd Row',
              onSelect: changableRowKeys => {
                let newSelectedRowKeys = [];
                newSelectedRowKeys = changableRowKeys.filter((key, index) => {
                  if (index % 2 !== 0) {
                    return false;
                  }
                  return true;
                });
                this.selectedRowKeys = newSelectedRowKeys;
              },
            },
            {
              key: 'even',
              text: 'Select Even Row',
              onSelect: changableRowKeys => {
                let newSelectedRowKeys = [];
                newSelectedRowKeys = changableRowKeys.filter((key, index) => {
                  if (index % 2 !== 0) {
                    return true;
                  }
                  return false;
                });
                this.selectedRowKeys = newSelectedRowKeys;
              },
            },
          ],
          onSelection: this.onSelection,
        };
      },
    },
    methods: {
      onSelectChange(selectedRowKeys) {
        console.log('selectedRowKeys changed: ', selectedRowKeys);
        this.selectedRowKeys = selectedRowKeys;
      },
    },
  };
</script>

Table 表格 - 图19

可选择

第一列是联动的选择框。

默认点击 checkbox 触发选择行为

<template>
  <a-table :rowSelection="rowSelection" :columns="columns" :dataSource="data">
    <a slot="name" slot-scope="text" href="javascript:;">{{text}}</a>
  </a-table>
</template>
<script>
  const columns = [
    {
      title: 'Name',
      dataIndex: 'name',
      scopedSlots: { customRender: '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',
    },
    {
      key: '4',
      name: 'Disabled User',
      age: 99,
      address: 'Sidney No. 1 Lake Park',
    },
  ];

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
    computed: {
      rowSelection() {
        const { selectedRowKeys } = this;
        return {
          onChange: (selectedRowKeys, selectedRows) => {
            console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
          },
          getCheckboxProps: record => ({
            props: {
              disabled: record.name === 'Disabled User', // Column configuration not to be checked
              name: record.name,
            },
          }),
        };
      },
    },
  };
</script>

Table 表格 - 图20

紧凑型

两种紧凑型的列表,小型列表只用于对话框内。

<template>
  <div id="components-table-demo-size">
    <h4>Middle size table</h4>
    <a-table :columns="columns" :dataSource="data" size="middle" />
    <h4>Small size table</h4>
    <a-table :columns="columns" :dataSource="data" size="small" />
  </div>
</template>
<script>
  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',
    },
  ];

  export default {
    data() {
      return {
        data,
        columns,
      };
    },
  };
</script>
<style>
  #components-table-demo-size h4 {
    margin-bottom: 16px;
  }
</style>

Table 表格 - 图21

template 风格的 API

使用 template 风格的 API

这个只是一个描述 columns 的语法糖,所以你不能用其他组件去包裹 ColumnColumnGroup

<template>
  <a-table :dataSource="data">
    <a-table-column-group>
      <span slot="title" style="color: #1890ff">Name</span>
      <a-table-column dataIndex="firstName" key="firstName">
        <span slot="title" style="color: #1890ff">First Name</span>
      </a-table-column>
      <a-table-column title="Last Name" dataIndex="lastName" key="lastName" />
    </a-table-column-group>
    <a-table-column title="Age" dataIndex="age" key="age" />
    <a-table-column title="Address" dataIndex="address" key="address" />
    <a-table-column title="Tags" dataIndex="tags" key="tags">
      <template slot-scope="tags">
        <span>
          <a-tag v-for="tag in tags" color="blue" :key="tag">{{tag}}</a-tag>
        </span>
      </template>
    </a-table-column>
    <a-table-column title="Action" key="action">
      <template slot-scope="text, record">
        <span>
          <a href="javascript:;">Action 一 {{record.firstName}}</a>
          <a-divider type="vertical" />
          <a href="javascript:;">Delete</a>
        </span>
      </template>
    </a-table-column>
  </a-table>
</template>
<script>
  const data = [
    {
      key: '1',
      firstName: 'John',
      lastName: 'Brown',
      age: 32,
      address: 'New York No. 1 Lake Park',
      tags: ['nice', 'developer'],
    },
    {
      key: '2',
      firstName: 'Jim',
      lastName: 'Green',
      age: 42,
      address: 'London No. 1 Lake Park',
      tags: ['loser'],
    },
    {
      key: '3',
      firstName: 'Joe',
      lastName: 'Black',
      age: 32,
      address: 'Sidney No. 1 Lake Park',
      tags: ['cool', 'teacher'],
    },
  ];

  export default {
    data() {
      return {
        data,
      };
    },
  };
</script>
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} />;

API

Table

参数说明类型默认值
bordered是否展示外边框和列边框booleanfalse
childrenColumnName指定树形结构的列名string[]children
columns表格列的配置描述,具体项见下表array-
components覆盖默认的 table 元素object-
dataSource数据数组any[]
defaultExpandAllRows初始时,是否展开所有行booleanfalse
defaultExpandedRowKeys默认展开的行string[]-
expandedRowKeys展开的行,控制属性string[]-
expandedRowRender额外的展开行Function(record, index, indent, expanded):VNode | slot="expandedRowRender" slot-scope="record, index, indent, expanded"-
expandIcon自定义展开图标Function(props):VNode | slot="expandIcon" slot-scope="props"-
expandRowByClick通过点击行来展开子行booleanfalse
footer表格尾部Function(currentPageData)|slot-scope
indentSize展示树形数据时,每层缩进的宽度,以 px 为单位number15
loading页面是否加载中boolean|objectfalse
locale默认文案设置,目前包括排序、过滤、空数据文案objectfilterConfirm: '确定' filterReset: '重置' emptyText: '暂无数据'
pagination分页器,参考配置项pagination文档,设为 false 时不展示和进行分页object
rowClassName表格行的类名Function(record, index):string-
rowKey表格行 key 的取值,可以是字符串或一个函数string|Function(record):string'key'
rowSelection列表项是否可选择,配置项objectnull
scroll设置横向或纵向滚动,也可用于指定滚动区域的宽和高,建议为 x 设置一个数字,如果要设置为 true,需要配合样式 .ant-table td { white-space: nowrap; }{ x: number | true, y: number }-
showHeader是否显示表头booleantrue
size表格大小default | middle | smalldefault
title表格标题Function(currentPageData)|slot-scope
customHeaderRow设置头部行属性Function(column, index)-
customRow设置行属性Function(record, index)-

事件

事件名称说明回调参数
expandedRowsChange展开的行变化时触发Function(expandedRows)
change分页、排序、筛选变化时触发Function(pagination, filters, sorter, { currentDataSource })
expand点击展开图标时触发Function(expanded, record)

customRow 用法

适用于 customRow customHeaderRow customCell customHeaderCell。遵循Vue jsx语法。

<Table
  customRow={(record) => {
    return {
      props: {
        xxx... //属性
      },
      on: { // 事件
        click: (event) => {},       // 点击行
        dblclick: (event) => {},
        contextmenu: (event) => {},
        mouseenter: (event) => {},  // 鼠标移入行
        mouseleave: (event) => {}
      },

    };
  )}
  customHeaderRow={(column) => {
    return {
      on: {
        click: () => {},        // 点击表头行
      }
    };
  )}
/>

Column

列描述数据对象,是 columns 中的一项,Column 使用相同的 API。

参数说明类型默认值
align设置列内容的对齐方式'left' | 'right' | 'center''left'
colSpan表头列合并,设置为 0 时,不渲染number
dataIndex列数据在数据项中对应的 key,支持 a.b.c 的嵌套写法string-
filterDropdown可以自定义筛选菜单,此函数只负责渲染图层,需要自行编写各种交互VNode | slot-scope-
filterDropdownVisible用于控制自定义筛选菜单是否可见boolean-
filtered标识数据是否经过过滤,筛选图标会高亮booleanfalse
filteredValue筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组string[]-
filterIcon自定义 fiter 图标。VNode | (filtered: boolean, column: Column) => vNode |slot |slot-scopefalse
filterMultiple是否多选booleantrue
filters表头的筛选菜单项object[]-
fixed列是否固定,可选 true(等效于 left) 'left' 'right'boolean|stringfalse
keyVue 需要的 key,如果已经设置了唯一的 dataIndex,可以忽略这个属性string-
customRender生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并,可参考 demo 表格行/列合并Function(text, record, index) {}|slot-scope-
sorter排序函数,本地排序使用一个函数(参考 Array.sort 的 compareFunction),需要服务端排序可设为 trueFunction|boolean-
sortOrder排序的受控属性,外界可用此控制列的排序,可设置为 'ascend' 'descend' falseboolean|string-
title列头显示文字string|slot-
width列宽度string|number-
customCell设置单元格属性Function(record, rowIndex)-
customHeaderCell设置头部单元格属性Function(column)-
onFilter本地模式下,确定筛选的运行函数, 使用 template 或 jsx 时作为filter事件使用Function-
onFilterDropdownVisibleChange自定义筛选菜单可见变化时调用,使用 template 或 jsx 时作为filterDropdownVisibleChange事件使用function(visible) {}-
slots使用 columns 时,可以通过该属性配置支持 slot 的属性,如 slots: { filterIcon: 'XXX'}object-
scopedSlots使用 columns 时,可以通过该属性配置支持 slot-scope 的属性,如 scopedSlots: { customRender: 'XXX'}object-

ColumnGroup

参数说明类型默认值
title列头显示文字string|slot-
slots使用 columns 时,可以通过该属性配置支持 slot 的属性,如 slots: { title: 'XXX'}object-

pagination

分页的配置项。

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

更多配置项,请查看 Pagination

rowSelection

选择功能的配置。

参数说明类型默认值
columnWidth自定义列表选择框宽度string|number-
columnTitle自定义列表选择框标题string|VNode-
fixed把选择框列固定在左边boolean-
getCheckboxProps选择框的默认属性配置Function(record)-
hideDefaultSelections去掉『全选』『反选』两个默认选项booleanfalse
selectedRowKeys指定选中项的 key 数组,需要和 onChange 进行配合string[][]
selections自定义选择配置项, 设为 true 时使用默认选择项object[]|booleantrue
type多选/单选,checkbox or radiostringcheckbox
onChange选中项发生变化时的回调Function(selectedRowKeys, selectedRows)-
onSelect用户手动选择/取消选择某列的回调Function(record, selected, selectedRows, nativeEvent)-
onSelectAll用户手动选择/取消选择所有列的回调Function(selected, selectedRows, changeRows)-
onSelectInvert用户手动选择反选的回调Function(selectedRows)-

selection

自定义选择配置项

参数说明类型默认值
keyVue 需要的 key,建议设置string-
text选择项显示的文字string|VNode-
onSelect选择项点击回调Function(changeableRowKeys)-

注意

在 Table 中,dataSourcecolumns 里的数据值都需要指定 key 值。对于 dataSource 默认将每列数据的 key 属性作为唯一的标识。

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

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