• Table 表格
    • 何时使用
    • 如何使用
    • 代码演示
      • 远程加载数据
      • 基本用法
      • 带边框
      • 表格行/列合并
      • 自定义筛选菜单
      • 可编辑单元格
      • 可编辑行
      • 树形数据展示
      • 可展开
      • 固定头和列
      • 固定列
      • 固定表头
      • 表头分组
      • 筛选和排序
      • 嵌套子表格
      • 可控的筛选和排序
      • 选择和操作
      • 自定义选择项
      • 可选择
      • 紧凑型
      • template 风格的 API
  • API
    • Table
    • 事件
      • customRow 用法
    • Column
    • ColumnGroup
    • pagination
    • rowSelection
    • selection
  • 注意

    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} />;