Table 表格

用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作。

基础表格

基础的表格展示用法。

el-table 元素中注入 data 对象数组后,在 el-table-column 中用 prop 属性来对应对象中的键名即可填入数据,用 label 属性来定义表格的列名。 可以使用 width 属性来定义列宽。

Table 表格 - 图1

  1. <template>
  2. <el-table :data="tableData" style="width: 100%">
  3. <el-table-column prop="date" label="Date" width="180" />
  4. <el-table-column prop="name" label="Name" width="180" />
  5. <el-table-column prop="address" label="Address" />
  6. </el-table>
  7. </template>
  8. <script lang="ts" setup>
  9. const tableData = [
  10. {
  11. date: '2016-05-03',
  12. name: 'Tom',
  13. address: 'No. 189, Grove St, Los Angeles',
  14. },
  15. {
  16. date: '2016-05-02',
  17. name: 'Tom',
  18. address: 'No. 189, Grove St, Los Angeles',
  19. },
  20. {
  21. date: '2016-05-04',
  22. name: 'Tom',
  23. address: 'No. 189, Grove St, Los Angeles',
  24. },
  25. {
  26. date: '2016-05-01',
  27. name: 'Tom',
  28. address: 'No. 189, Grove St, Los Angeles',
  29. },
  30. ]
  31. </script>

带斑马纹表格

使用带斑马纹的表格,可以更容易区分出不同行的数据。

stripe 属性可以创建带斑马纹的表格。 如果 true, 表格将会带有斑马纹。

Table 表格 - 图2

  1. <template>
  2. <el-table :data="tableData" stripe style="width: 100%">
  3. <el-table-column prop="date" label="Date" width="180" />
  4. <el-table-column prop="name" label="Name" width="180" />
  5. <el-table-column prop="address" label="Address" />
  6. </el-table>
  7. </template>
  8. <script lang="ts" setup>
  9. const tableData = [
  10. {
  11. date: '2016-05-03',
  12. name: 'Tom',
  13. address: 'No. 189, Grove St, Los Angeles',
  14. },
  15. {
  16. date: '2016-05-02',
  17. name: 'Tom',
  18. address: 'No. 189, Grove St, Los Angeles',
  19. },
  20. {
  21. date: '2016-05-04',
  22. name: 'Tom',
  23. address: 'No. 189, Grove St, Los Angeles',
  24. },
  25. {
  26. date: '2016-05-01',
  27. name: 'Tom',
  28. address: 'No. 189, Grove St, Los Angeles',
  29. },
  30. ]
  31. </script>

带边框表格

默认情况下,Table 组件是不具有竖直方向的边框的, 如果需要,可以使用 border 属性,把该属性设置为 true 即可启用。

Table 表格 - 图3

  1. <template>
  2. <el-table :data="tableData" border style="width: 100%">
  3. <el-table-column prop="date" label="Date" width="180" />
  4. <el-table-column prop="name" label="Name" width="180" />
  5. <el-table-column prop="address" label="Address" />
  6. </el-table>
  7. </template>
  8. <script lang="ts" setup>
  9. const tableData = [
  10. {
  11. date: '2016-05-03',
  12. name: 'Tom',
  13. address: 'No. 189, Grove St, Los Angeles',
  14. },
  15. {
  16. date: '2016-05-02',
  17. name: 'Tom',
  18. address: 'No. 189, Grove St, Los Angeles',
  19. },
  20. {
  21. date: '2016-05-04',
  22. name: 'Tom',
  23. address: 'No. 189, Grove St, Los Angeles',
  24. },
  25. {
  26. date: '2016-05-01',
  27. name: 'Tom',
  28. address: 'No. 189, Grove St, Los Angeles',
  29. },
  30. ]
  31. </script>

带状态表格

可将表格内容 highlight 显示,方便区分「成功、信息、警告、危险」等内容。

可以通过指定 Table 组件的 row-class-name 属性来为 Table 中的某一行添加 class, 表明该行处于某种状态。

Table 表格 - 图4

  1. <template>
  2. <el-table
  3. :data="tableData"
  4. style="width: 100%"
  5. :row-class-name="tableRowClassName"
  6. >
  7. <el-table-column prop="date" label="Date" width="180" />
  8. <el-table-column prop="name" label="Name" width="180" />
  9. <el-table-column prop="address" label="Address" />
  10. </el-table>
  11. </template>
  12. <script lang="ts" setup>
  13. interface User {
  14. date: string
  15. name: string
  16. address: string
  17. }
  18. const tableRowClassName = ({
  19. row,
  20. rowIndex,
  21. }: {
  22. row: User
  23. rowIndex: number
  24. }) => {
  25. if (rowIndex === 1) {
  26. return 'warning-row'
  27. } else if (rowIndex === 3) {
  28. return 'success-row'
  29. }
  30. return ''
  31. }
  32. const tableData: User[] = [
  33. {
  34. date: '2016-05-03',
  35. name: 'Tom',
  36. address: 'No. 189, Grove St, Los Angeles',
  37. },
  38. {
  39. date: '2016-05-02',
  40. name: 'Tom',
  41. address: 'No. 189, Grove St, Los Angeles',
  42. },
  43. {
  44. date: '2016-05-04',
  45. name: 'Tom',
  46. address: 'No. 189, Grove St, Los Angeles',
  47. },
  48. {
  49. date: '2016-05-01',
  50. name: 'Tom',
  51. address: 'No. 189, Grove St, Los Angeles',
  52. },
  53. ]
  54. </script>
  55. <style>
  56. .el-table .warning-row {
  57. --el-table-tr-bg-color: var(--el-color-warning-light-9);
  58. }
  59. .el-table .success-row {
  60. --el-table-tr-bg-color: var(--el-color-success-light-9);
  61. }
  62. </style>

固定表头

纵向内容过多时,可选择固定表头。

只要在 el-table 元素中定义了 height 属性,即可实现固定表头的表格,而不需要额外的代码。

Table 表格 - 图5

  1. <template>
  2. <el-table :data="tableData" height="250" style="width: 100%">
  3. <el-table-column prop="date" label="Date" width="180" />
  4. <el-table-column prop="name" label="Name" width="180" />
  5. <el-table-column prop="address" label="Address" />
  6. </el-table>
  7. </template>
  8. <script lang="ts" setup>
  9. const tableData = [
  10. {
  11. date: '2016-05-03',
  12. name: 'Tom',
  13. address: 'No. 189, Grove St, Los Angeles',
  14. },
  15. {
  16. date: '2016-05-02',
  17. name: 'Tom',
  18. address: 'No. 189, Grove St, Los Angeles',
  19. },
  20. {
  21. date: '2016-05-04',
  22. name: 'Tom',
  23. address: 'No. 189, Grove St, Los Angeles',
  24. },
  25. {
  26. date: '2016-05-01',
  27. name: 'Tom',
  28. address: 'No. 189, Grove St, Los Angeles',
  29. },
  30. {
  31. date: '2016-05-08',
  32. name: 'Tom',
  33. address: 'No. 189, Grove St, Los Angeles',
  34. },
  35. {
  36. date: '2016-05-06',
  37. name: 'Tom',
  38. address: 'No. 189, Grove St, Los Angeles',
  39. },
  40. {
  41. date: '2016-05-07',
  42. name: 'Tom',
  43. address: 'No. 189, Grove St, Los Angeles',
  44. },
  45. ]
  46. </script>

固定列

横向内容过多时,可选择固定列。

固定列需要使用 fixed 属性,它接受 Boolean 值 如果为 true, 列将被左侧固定. 它还接受传入字符串,left 或 right,表示左边固定还是右边固定。

Table 表格 - 图6

  1. <template>
  2. <el-table :data="tableData" style="width: 100%">
  3. <el-table-column fixed prop="date" label="Date" width="150" />
  4. <el-table-column prop="name" label="Name" width="120" />
  5. <el-table-column prop="state" label="State" width="120" />
  6. <el-table-column prop="city" label="City" width="120" />
  7. <el-table-column prop="address" label="Address" width="600" />
  8. <el-table-column prop="zip" label="Zip" width="120" />
  9. <el-table-column fixed="right" label="Operations" width="120">
  10. <template #default>
  11. <el-button link type="primary" size="small" @click="handleClick"
  12. >Detail</el-button
  13. >
  14. <el-button link type="primary" size="small">Edit</el-button>
  15. </template>
  16. </el-table-column>
  17. </el-table>
  18. </template>
  19. <script lang="ts" setup>
  20. const handleClick = () => {
  21. console.log('click')
  22. }
  23. const tableData = [
  24. {
  25. date: '2016-05-03',
  26. name: 'Tom',
  27. state: 'California',
  28. city: 'Los Angeles',
  29. address: 'No. 189, Grove St, Los Angeles',
  30. zip: 'CA 90036',
  31. tag: 'Home',
  32. },
  33. {
  34. date: '2016-05-02',
  35. name: 'Tom',
  36. state: 'California',
  37. city: 'Los Angeles',
  38. address: 'No. 189, Grove St, Los Angeles',
  39. zip: 'CA 90036',
  40. tag: 'Office',
  41. },
  42. {
  43. date: '2016-05-04',
  44. name: 'Tom',
  45. state: 'California',
  46. city: 'Los Angeles',
  47. address: 'No. 189, Grove St, Los Angeles',
  48. zip: 'CA 90036',
  49. tag: 'Home',
  50. },
  51. {
  52. date: '2016-05-01',
  53. name: 'Tom',
  54. state: 'California',
  55. city: 'Los Angeles',
  56. address: 'No. 189, Grove St, Los Angeles',
  57. zip: 'CA 90036',
  58. tag: 'Office',
  59. },
  60. ]
  61. </script>

固定列和表头

横纵内容过多时,可选择固定列和表头。

固定列和表头可以同时使用,只需要将上述两个属性分别设置好即可。

Table 表格 - 图7

  1. <template>
  2. <el-table :data="tableData" style="width: 100%" height="250">
  3. <el-table-column fixed prop="date" label="Date" width="150" />
  4. <el-table-column prop="name" label="Name" width="120" />
  5. <el-table-column prop="state" label="State" width="120" />
  6. <el-table-column prop="city" label="City" width="320" />
  7. <el-table-column prop="address" label="Address" width="600" />
  8. <el-table-column prop="zip" label="Zip" width="120" />
  9. </el-table>
  10. </template>
  11. <script lang="ts" setup>
  12. const tableData = [
  13. {
  14. date: '2016-05-03',
  15. name: 'Tom',
  16. state: 'California',
  17. city: 'Los Angeles',
  18. address: 'No. 189, Grove St, Los Angeles',
  19. zip: 'CA 90036',
  20. },
  21. {
  22. date: '2016-05-02',
  23. name: 'Tom',
  24. state: 'California',
  25. city: 'Los Angeles',
  26. address: 'No. 189, Grove St, Los Angeles',
  27. zip: 'CA 90036',
  28. },
  29. {
  30. date: '2016-05-04',
  31. name: 'Tom',
  32. state: 'California',
  33. city: 'Los Angeles',
  34. address: 'No. 189, Grove St, Los Angeles',
  35. zip: 'CA 90036',
  36. },
  37. {
  38. date: '2016-05-01',
  39. name: 'Tom',
  40. state: 'California',
  41. city: 'Los Angeles',
  42. address: 'No. 189, Grove St, Los Angeles',
  43. zip: 'CA 90036',
  44. },
  45. {
  46. date: '2016-05-08',
  47. name: 'Tom',
  48. state: 'California',
  49. city: 'Los Angeles',
  50. address: 'No. 189, Grove St, Los Angeles',
  51. zip: 'CA 90036',
  52. },
  53. {
  54. date: '2016-05-06',
  55. name: 'Tom',
  56. state: 'California',
  57. city: 'Los Angeles',
  58. address: 'No. 189, Grove St, Los Angeles',
  59. zip: 'CA 90036',
  60. },
  61. {
  62. date: '2016-05-07',
  63. name: 'Tom',
  64. state: 'California',
  65. city: 'Los Angeles',
  66. address: 'No. 189, Grove St, Los Angeles',
  67. zip: 'CA 90036',
  68. },
  69. ]
  70. </script>

流体高度

当数据量动态变化时,可以为 Table 设置一个最大高度。

通过设置 max-height 属性为 Table 指定最大高度。 此时若表格所需的高度大于最大高度,则会显示一个滚动条。

Table 表格 - 图8

  1. <template>
  2. <el-table :data="tableData" style="width: 100%" max-height="250">
  3. <el-table-column fixed prop="date" label="Date" width="150" />
  4. <el-table-column prop="name" label="Name" width="120" />
  5. <el-table-column prop="state" label="State" width="120" />
  6. <el-table-column prop="city" label="City" width="120" />
  7. <el-table-column prop="address" label="Address" width="600" />
  8. <el-table-column prop="zip" label="Zip" width="120" />
  9. <el-table-column fixed="right" label="Operations" width="120">
  10. <template #default="scope">
  11. <el-button
  12. link
  13. type="primary"
  14. size="small"
  15. @click.prevent="deleteRow(scope.$index)"
  16. >
  17. Remove
  18. </el-button>
  19. </template>
  20. </el-table-column>
  21. </el-table>
  22. <el-button class="mt-4" style="width: 100%" @click="onAddItem"
  23. >Add Item</el-button
  24. >
  25. </template>
  26. <script lang="ts" setup>
  27. import { ref } from 'vue'
  28. import dayjs from 'dayjs'
  29. const now = new Date()
  30. const tableData = ref([
  31. {
  32. date: '2016-05-01',
  33. name: 'Tom',
  34. state: 'California',
  35. city: 'Los Angeles',
  36. address: 'No. 189, Grove St, Los Angeles',
  37. zip: 'CA 90036',
  38. },
  39. {
  40. date: '2016-05-02',
  41. name: 'Tom',
  42. state: 'California',
  43. city: 'Los Angeles',
  44. address: 'No. 189, Grove St, Los Angeles',
  45. zip: 'CA 90036',
  46. },
  47. {
  48. date: '2016-05-03',
  49. name: 'Tom',
  50. state: 'California',
  51. city: 'Los Angeles',
  52. address: 'No. 189, Grove St, Los Angeles',
  53. zip: 'CA 90036',
  54. },
  55. ])
  56. const deleteRow = (index: number) => {
  57. tableData.value.splice(index, 1)
  58. }
  59. const onAddItem = () => {
  60. now.setDate(now.getDate() + 1)
  61. tableData.value.push({
  62. date: dayjs(now).format('YYYY-MM-DD'),
  63. name: 'Tom',
  64. state: 'California',
  65. city: 'Los Angeles',
  66. address: 'No. 189, Grove St, Los Angeles',
  67. zip: 'CA 90036',
  68. })
  69. }
  70. </script>

多级表头

数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。

只需要在 el-table-column 里面嵌套 el-table-column,就可以实现多级表头。

Table 表格 - 图9

  1. <template>
  2. <el-table :data="tableData" style="width: 100%">
  3. <el-table-column prop="date" label="Date" width="150" />
  4. <el-table-column label="Delivery Info">
  5. <el-table-column prop="name" label="Name" width="120" />
  6. <el-table-column label="Address Info">
  7. <el-table-column prop="state" label="State" width="120" />
  8. <el-table-column prop="city" label="City" width="120" />
  9. <el-table-column prop="address" label="Address" />
  10. <el-table-column prop="zip" label="Zip" width="120" />
  11. </el-table-column>
  12. </el-table-column>
  13. </el-table>
  14. </template>
  15. <script lang="ts" setup>
  16. const tableData = [
  17. {
  18. date: '2016-05-03',
  19. name: 'Tom',
  20. state: 'California',
  21. city: 'Los Angeles',
  22. address: 'No. 189, Grove St, Los Angeles',
  23. zip: 'CA 90036',
  24. },
  25. {
  26. date: '2016-05-02',
  27. name: 'Tom',
  28. state: 'California',
  29. city: 'Los Angeles',
  30. address: 'No. 189, Grove St, Los Angeles',
  31. zip: 'CA 90036',
  32. },
  33. {
  34. date: '2016-05-04',
  35. name: 'Tom',
  36. state: 'California',
  37. city: 'Los Angeles',
  38. address: 'No. 189, Grove St, Los Angeles',
  39. zip: 'CA 90036',
  40. },
  41. {
  42. date: '2016-05-01',
  43. name: 'Tom',
  44. state: 'California',
  45. city: 'Los Angeles',
  46. address: 'No. 189, Grove St, Los Angeles',
  47. zip: 'CA 90036',
  48. },
  49. {
  50. date: '2016-05-08',
  51. name: 'Tom',
  52. state: 'California',
  53. city: 'Los Angeles',
  54. address: 'No. 189, Grove St, Los Angeles',
  55. zip: 'CA 90036',
  56. },
  57. {
  58. date: '2016-05-06',
  59. name: 'Tom',
  60. state: 'California',
  61. city: 'Los Angeles',
  62. address: 'No. 189, Grove St, Los Angeles',
  63. zip: 'CA 90036',
  64. },
  65. {
  66. date: '2016-05-07',
  67. name: 'Tom',
  68. state: 'California',
  69. city: 'Los Angeles',
  70. address: 'No. 189, Grove St, Los Angeles',
  71. zip: 'CA 90036',
  72. },
  73. ]
  74. </script>

单选

选择单行数据时使用色块表示。

Table 组件提供了单选的支持, 只需要配置 highlight-current-row 属性即可实现单选。 之后由 current-change 事件来管理选中时触发的事件,它会传入 currentRowoldCurrentRow。 如果需要显示索引,可以增加一列 el-table-column,设置 type 属性为 index 即可显示从 1 开始的索引号。

Table 表格 - 图10

  1. <template>
  2. <el-table
  3. ref="singleTableRef"
  4. :data="tableData"
  5. highlight-current-row
  6. style="width: 100%"
  7. @current-change="handleCurrentChange"
  8. >
  9. <el-table-column type="index" width="50" />
  10. <el-table-column property="date" label="Date" width="120" />
  11. <el-table-column property="name" label="Name" width="120" />
  12. <el-table-column property="address" label="Address" />
  13. </el-table>
  14. <div style="margin-top: 20px">
  15. <el-button @click="setCurrent(tableData[1])">Select second row</el-button>
  16. <el-button @click="setCurrent()">Clear selection</el-button>
  17. </div>
  18. </template>
  19. <script lang="ts" setup>
  20. import { ref } from 'vue'
  21. import { ElTable } from 'element-plus'
  22. interface User {
  23. date: string
  24. name: string
  25. address: string
  26. }
  27. const currentRow = ref()
  28. const singleTableRef = ref<InstanceType<typeof ElTable>>()
  29. const setCurrent = (row?: User) => {
  30. singleTableRef.value!.setCurrentRow(row)
  31. }
  32. const handleCurrentChange = (val: User | undefined) => {
  33. currentRow.value = val
  34. }
  35. const tableData: User[] = [
  36. {
  37. date: '2016-05-03',
  38. name: 'Tom',
  39. address: 'No. 189, Grove St, Los Angeles',
  40. },
  41. {
  42. date: '2016-05-02',
  43. name: 'Tom',
  44. address: 'No. 189, Grove St, Los Angeles',
  45. },
  46. {
  47. date: '2016-05-04',
  48. name: 'Tom',
  49. address: 'No. 189, Grove St, Los Angeles',
  50. },
  51. {
  52. date: '2016-05-01',
  53. name: 'Tom',
  54. address: 'No. 189, Grove St, Los Angeles',
  55. },
  56. ]
  57. </script>

多选

你也可以选择多行。

实现多选非常简单: 手动添加一个 el-table-column,设 type 属性为 selection 即可; 除了多选,这里还使用到了 show-overflow-tooltip属性。 默认情况下,如果单元格内容过长,会占用多行显示。 若需要单行显示可以使用 show-overflow-tooltip 属性,它接受一个 Boolean, 为 true 时多余的内容会在 hover 时以 tooltip 的形式显示出来。

Table 表格 - 图11

  1. <template>
  2. <el-table
  3. ref="multipleTableRef"
  4. :data="tableData"
  5. style="width: 100%"
  6. @selection-change="handleSelectionChange"
  7. >
  8. <el-table-column type="selection" width="55" />
  9. <el-table-column label="Date" width="120">
  10. <template #default="scope">{{ scope.row.date }}</template>
  11. </el-table-column>
  12. <el-table-column property="name" label="Name" width="120" />
  13. <el-table-column property="address" label="Address" show-overflow-tooltip />
  14. </el-table>
  15. <div style="margin-top: 20px">
  16. <el-button @click="toggleSelection([tableData[1], tableData[2]])"
  17. >Toggle selection status of second and third rows</el-button
  18. >
  19. <el-button @click="toggleSelection()">Clear selection</el-button>
  20. </div>
  21. </template>
  22. <script lang="ts" setup>
  23. import { ref } from 'vue'
  24. import { ElTable } from 'element-plus'
  25. interface User {
  26. date: string
  27. name: string
  28. address: string
  29. }
  30. const multipleTableRef = ref<InstanceType<typeof ElTable>>()
  31. const multipleSelection = ref<User[]>([])
  32. const toggleSelection = (rows?: User[]) => {
  33. if (rows) {
  34. rows.forEach((row) => {
  35. // TODO: improvement typing when refactor table
  36. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  37. // @ts-expect-error
  38. multipleTableRef.value!.toggleRowSelection(row, undefined)
  39. })
  40. } else {
  41. multipleTableRef.value!.clearSelection()
  42. }
  43. }
  44. const handleSelectionChange = (val: User[]) => {
  45. multipleSelection.value = val
  46. }
  47. const tableData: User[] = [
  48. {
  49. date: '2016-05-03',
  50. name: 'Tom',
  51. address: 'No. 189, Grove St, Los Angeles',
  52. },
  53. {
  54. date: '2016-05-02',
  55. name: 'Tom',
  56. address: 'No. 189, Grove St, Los Angeles',
  57. },
  58. {
  59. date: '2016-05-04',
  60. name: 'Tom',
  61. address: 'No. 189, Grove St, Los Angeles',
  62. },
  63. {
  64. date: '2016-05-01',
  65. name: 'Tom',
  66. address: 'No. 189, Grove St, Los Angeles',
  67. },
  68. {
  69. date: '2016-05-08',
  70. name: 'Tom',
  71. address: 'No. 189, Grove St, Los Angeles',
  72. },
  73. {
  74. date: '2016-05-06',
  75. name: 'Tom',
  76. address: 'No. 189, Grove St, Los Angeles',
  77. },
  78. {
  79. date: '2016-05-07',
  80. name: 'Tom',
  81. address: 'No. 189, Grove St, Los Angeles',
  82. },
  83. ]
  84. </script>

排序

对表格进行排序,可快速查找或对比数据。

在列中设置 sortable 属性即可实现以该列为基准的排序, 接受一个 Boolean,默认为 false。 可以通过 Table 的 default-sort 属性设置默认的排序列和排序顺序。 可以使用 sort-method 或者 sort-by 使用自定义的排序规则。 如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件, 在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。 在本例中,我们还使用了 formatter 属性,它用于格式化指定列的值, 接受一个 Function,会传入两个参数:rowcolumn, 可以根据自己的需求进行处理。

Table 表格 - 图12

  1. <template>
  2. <el-table
  3. :data="tableData"
  4. :default-sort="{ prop: 'date', order: 'descending' }"
  5. style="width: 100%"
  6. >
  7. <el-table-column prop="date" label="Date" sortable width="180" />
  8. <el-table-column prop="name" label="Name" width="180" />
  9. <el-table-column prop="address" label="Address" :formatter="formatter" />
  10. </el-table>
  11. </template>
  12. <script lang="ts" setup>
  13. import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
  14. interface User {
  15. date: string
  16. name: string
  17. address: string
  18. }
  19. const formatter = (row: User, column: TableColumnCtx<User>) => {
  20. return row.address
  21. }
  22. const tableData: User[] = [
  23. {
  24. date: '2016-05-03',
  25. name: 'Tom',
  26. address: 'No. 189, Grove St, Los Angeles',
  27. },
  28. {
  29. date: '2016-05-02',
  30. name: 'Tom',
  31. address: 'No. 189, Grove St, Los Angeles',
  32. },
  33. {
  34. date: '2016-05-04',
  35. name: 'Tom',
  36. address: 'No. 189, Grove St, Los Angeles',
  37. },
  38. {
  39. date: '2016-05-01',
  40. name: 'Tom',
  41. address: 'No. 189, Grove St, Los Angeles',
  42. },
  43. ]
  44. </script>

筛选

对表格进行筛选,可快速查找到自己想看的数据。

在列中设置 filtersfilter-method 属性即可开启该列的筛选, filters 是一个数组,filter-method 是一个方法,它用于决定某些数据是否显示, 会传入三个参数:value, rowcolumn

Table 表格 - 图13

  1. <template>
  2. <el-button @click="resetDateFilter">reset date filter</el-button>
  3. <el-button @click="clearFilter">reset all filters</el-button>
  4. <el-table ref="tableRef" row-key="date" :data="tableData" style="width: 100%">
  5. <el-table-column
  6. prop="date"
  7. label="Date"
  8. sortable
  9. width="180"
  10. column-key="date"
  11. :filters="[
  12. { text: '2016-05-01', value: '2016-05-01' },
  13. { text: '2016-05-02', value: '2016-05-02' },
  14. { text: '2016-05-03', value: '2016-05-03' },
  15. { text: '2016-05-04', value: '2016-05-04' },
  16. ]"
  17. :filter-method="filterHandler"
  18. />
  19. <el-table-column prop="name" label="Name" width="180" />
  20. <el-table-column prop="address" label="Address" :formatter="formatter" />
  21. <el-table-column
  22. prop="tag"
  23. label="Tag"
  24. width="100"
  25. :filters="[
  26. { text: 'Home', value: 'Home' },
  27. { text: 'Office', value: 'Office' },
  28. ]"
  29. :filter-method="filterTag"
  30. filter-placement="bottom-end"
  31. >
  32. <template #default="scope">
  33. <el-tag
  34. :type="scope.row.tag === 'Home' ? '' : 'success'"
  35. disable-transitions
  36. >{{ scope.row.tag }}</el-tag
  37. >
  38. </template>
  39. </el-table-column>
  40. </el-table>
  41. </template>
  42. <script lang="ts" setup>
  43. import { ref } from 'vue'
  44. import { ElTable } from 'element-plus'
  45. import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
  46. interface User {
  47. date: string
  48. name: string
  49. address: string
  50. tag: string
  51. }
  52. const tableRef = ref<InstanceType<typeof ElTable>>()
  53. const resetDateFilter = () => {
  54. tableRef.value!.clearFilter(['date'])
  55. }
  56. // TODO: improvement typing when refactor table
  57. const clearFilter = () => {
  58. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  59. // @ts-expect-error
  60. tableRef.value!.clearFilter()
  61. }
  62. const formatter = (row: User, column: TableColumnCtx<User>) => {
  63. return row.address
  64. }
  65. const filterTag = (value: string, row: User) => {
  66. return row.tag === value
  67. }
  68. const filterHandler = (
  69. value: string,
  70. row: User,
  71. column: TableColumnCtx<User>
  72. ) => {
  73. const property = column['property']
  74. return row[property] === value
  75. }
  76. const tableData: User[] = [
  77. {
  78. date: '2016-05-03',
  79. name: 'Tom',
  80. address: 'No. 189, Grove St, Los Angeles',
  81. tag: 'Home',
  82. },
  83. {
  84. date: '2016-05-02',
  85. name: 'Tom',
  86. address: 'No. 189, Grove St, Los Angeles',
  87. tag: 'Office',
  88. },
  89. {
  90. date: '2016-05-04',
  91. name: 'Tom',
  92. address: 'No. 189, Grove St, Los Angeles',
  93. tag: 'Home',
  94. },
  95. {
  96. date: '2016-05-01',
  97. name: 'Tom',
  98. address: 'No. 189, Grove St, Los Angeles',
  99. tag: 'Office',
  100. },
  101. ]
  102. </script>

自定义列模板

自定义列的显示内容,可组合其他组件使用。

通过 slot 可以获取到 row, column, $index 和 store(table 内部的状态管理)的数据,用法参考 demo。

Table 表格 - 图14

  1. <template>
  2. <el-table :data="tableData" style="width: 100%">
  3. <el-table-column label="Date" width="180">
  4. <template #default="scope">
  5. <div style="display: flex; align-items: center">
  6. <el-icon><timer /></el-icon>
  7. <span style="margin-left: 10px">{{ scope.row.date }}</span>
  8. </div>
  9. </template>
  10. </el-table-column>
  11. <el-table-column label="Name" width="180">
  12. <template #default="scope">
  13. <el-popover effect="light" trigger="hover" placement="top" width="auto">
  14. <template #default>
  15. <div>name: {{ scope.row.name }}</div>
  16. <div>address: {{ scope.row.address }}</div>
  17. </template>
  18. <template #reference>
  19. <el-tag>{{ scope.row.name }}</el-tag>
  20. </template>
  21. </el-popover>
  22. </template>
  23. </el-table-column>
  24. <el-table-column label="Operations">
  25. <template #default="scope">
  26. <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
  27. >Edit</el-button
  28. >
  29. <el-button
  30. size="small"
  31. type="danger"
  32. @click="handleDelete(scope.$index, scope.row)"
  33. >Delete</el-button
  34. >
  35. </template>
  36. </el-table-column>
  37. </el-table>
  38. </template>
  39. <script lang="ts" setup>
  40. import { Timer } from '@element-plus/icons-vue'
  41. interface User {
  42. date: string
  43. name: string
  44. address: string
  45. }
  46. const handleEdit = (index: number, row: User) => {
  47. console.log(index, row)
  48. }
  49. const handleDelete = (index: number, row: User) => {
  50. console.log(index, row)
  51. }
  52. const tableData: User[] = [
  53. {
  54. date: '2016-05-03',
  55. name: 'Tom',
  56. address: 'No. 189, Grove St, Los Angeles',
  57. },
  58. {
  59. date: '2016-05-02',
  60. name: 'Tom',
  61. address: 'No. 189, Grove St, Los Angeles',
  62. },
  63. {
  64. date: '2016-05-04',
  65. name: 'Tom',
  66. address: 'No. 189, Grove St, Los Angeles',
  67. },
  68. {
  69. date: '2016-05-01',
  70. name: 'Tom',
  71. address: 'No. 189, Grove St, Los Angeles',
  72. },
  73. ]
  74. </script>

自定义表头

表头支持自定义。

通过设置 slot 来自定义表头。

Table 表格 - 图15

  1. <template>
  2. <el-table :data="filterTableData" style="width: 100%">
  3. <el-table-column label="Date" prop="date" />
  4. <el-table-column label="Name" prop="name" />
  5. <el-table-column align="right">
  6. <template #header>
  7. <el-input v-model="search" size="small" placeholder="Type to search" />
  8. </template>
  9. <template #default="scope">
  10. <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
  11. >Edit</el-button
  12. >
  13. <el-button
  14. size="small"
  15. type="danger"
  16. @click="handleDelete(scope.$index, scope.row)"
  17. >Delete</el-button
  18. >
  19. </template>
  20. </el-table-column>
  21. </el-table>
  22. </template>
  23. <script lang="ts" setup>
  24. import { computed, ref } from 'vue'
  25. interface User {
  26. date: string
  27. name: string
  28. address: string
  29. }
  30. const search = ref('')
  31. const filterTableData = computed(() =>
  32. tableData.filter(
  33. (data) =>
  34. !search.value ||
  35. data.name.toLowerCase().includes(search.value.toLowerCase())
  36. )
  37. )
  38. const handleEdit = (index: number, row: User) => {
  39. console.log(index, row)
  40. }
  41. const handleDelete = (index: number, row: User) => {
  42. console.log(index, row)
  43. }
  44. const tableData: User[] = [
  45. {
  46. date: '2016-05-03',
  47. name: 'Tom',
  48. address: 'No. 189, Grove St, Los Angeles',
  49. },
  50. {
  51. date: '2016-05-02',
  52. name: 'John',
  53. address: 'No. 189, Grove St, Los Angeles',
  54. },
  55. {
  56. date: '2016-05-04',
  57. name: 'Morgan',
  58. address: 'No. 189, Grove St, Los Angeles',
  59. },
  60. {
  61. date: '2016-05-01',
  62. name: 'Jessy',
  63. address: 'No. 189, Grove St, Los Angeles',
  64. },
  65. ]
  66. </script>

展开行

当行内容过多并且不想显示横向滚动条时,可以使用 Table 展开行功能。

通过设置 type=”expand” 和 slot 可以开启展开行功能, el-table-column 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 slot 相同。

Table 表格 - 图16

  1. <template>
  2. switch parent border: <el-switch v-model="parentBorder" /> switch child
  3. border: <el-switch v-model="childBorder" />
  4. <el-table :data="tableData" :border="parentBorder" style="width: 100%">
  5. <el-table-column type="expand">
  6. <template #default="props">
  7. <div m="4">
  8. <p m="t-0 b-2">State: {{ props.row.state }}</p>
  9. <p m="t-0 b-2">City: {{ props.row.city }}</p>
  10. <p m="t-0 b-2">Address: {{ props.row.address }}</p>
  11. <p m="t-0 b-2">Zip: {{ props.row.zip }}</p>
  12. <h3>Family</h3>
  13. <el-table :data="props.row.family" :border="childBorder">
  14. <el-table-column label="Name" prop="name" />
  15. <el-table-column label="State" prop="state" />
  16. <el-table-column label="City" prop="city" />
  17. <el-table-column label="Address" prop="address" />
  18. <el-table-column label="Zip" prop="zip" />
  19. </el-table>
  20. </div>
  21. </template>
  22. </el-table-column>
  23. <el-table-column label="Date" prop="date" />
  24. <el-table-column label="Name" prop="name" />
  25. </el-table>
  26. </template>
  27. <script lang="ts" setup>
  28. import { ref } from 'vue'
  29. const parentBorder = ref(false)
  30. const childBorder = ref(false)
  31. const tableData = [
  32. {
  33. date: '2016-05-03',
  34. name: 'Tom',
  35. state: 'California',
  36. city: 'San Francisco',
  37. address: '3650 21st St, San Francisco',
  38. zip: 'CA 94114',
  39. family: [
  40. {
  41. name: 'Jerry',
  42. state: 'California',
  43. city: 'San Francisco',
  44. address: '3650 21st St, San Francisco',
  45. zip: 'CA 94114',
  46. },
  47. {
  48. name: 'Spike',
  49. state: 'California',
  50. city: 'San Francisco',
  51. address: '3650 21st St, San Francisco',
  52. zip: 'CA 94114',
  53. },
  54. {
  55. name: 'Tyke',
  56. state: 'California',
  57. city: 'San Francisco',
  58. address: '3650 21st St, San Francisco',
  59. zip: 'CA 94114',
  60. },
  61. ],
  62. },
  63. {
  64. date: '2016-05-02',
  65. name: 'Tom',
  66. state: 'California',
  67. city: 'San Francisco',
  68. address: '3650 21st St, San Francisco',
  69. zip: 'CA 94114',
  70. family: [
  71. {
  72. name: 'Jerry',
  73. state: 'California',
  74. city: 'San Francisco',
  75. address: '3650 21st St, San Francisco',
  76. zip: 'CA 94114',
  77. },
  78. {
  79. name: 'Spike',
  80. state: 'California',
  81. city: 'San Francisco',
  82. address: '3650 21st St, San Francisco',
  83. zip: 'CA 94114',
  84. },
  85. {
  86. name: 'Tyke',
  87. state: 'California',
  88. city: 'San Francisco',
  89. address: '3650 21st St, San Francisco',
  90. zip: 'CA 94114',
  91. },
  92. ],
  93. },
  94. {
  95. date: '2016-05-04',
  96. name: 'Tom',
  97. state: 'California',
  98. city: 'San Francisco',
  99. address: '3650 21st St, San Francisco',
  100. zip: 'CA 94114',
  101. family: [
  102. {
  103. name: 'Jerry',
  104. state: 'California',
  105. city: 'San Francisco',
  106. address: '3650 21st St, San Francisco',
  107. zip: 'CA 94114',
  108. },
  109. {
  110. name: 'Spike',
  111. state: 'California',
  112. city: 'San Francisco',
  113. address: '3650 21st St, San Francisco',
  114. zip: 'CA 94114',
  115. },
  116. {
  117. name: 'Tyke',
  118. state: 'California',
  119. city: 'San Francisco',
  120. address: '3650 21st St, San Francisco',
  121. zip: 'CA 94114',
  122. },
  123. ],
  124. },
  125. {
  126. date: '2016-05-01',
  127. name: 'Tom',
  128. state: 'California',
  129. city: 'San Francisco',
  130. address: '3650 21st St, San Francisco',
  131. zip: 'CA 94114',
  132. family: [
  133. {
  134. name: 'Jerry',
  135. state: 'California',
  136. city: 'San Francisco',
  137. address: '3650 21st St, San Francisco',
  138. zip: 'CA 94114',
  139. },
  140. {
  141. name: 'Spike',
  142. state: 'California',
  143. city: 'San Francisco',
  144. address: '3650 21st St, San Francisco',
  145. zip: 'CA 94114',
  146. },
  147. {
  148. name: 'Tyke',
  149. state: 'California',
  150. city: 'San Francisco',
  151. address: '3650 21st St, San Francisco',
  152. zip: 'CA 94114',
  153. },
  154. ],
  155. },
  156. {
  157. date: '2016-05-08',
  158. name: 'Tom',
  159. state: 'California',
  160. city: 'San Francisco',
  161. address: '3650 21st St, San Francisco',
  162. zip: 'CA 94114',
  163. family: [
  164. {
  165. name: 'Jerry',
  166. state: 'California',
  167. city: 'San Francisco',
  168. address: '3650 21st St, San Francisco',
  169. zip: 'CA 94114',
  170. },
  171. {
  172. name: 'Spike',
  173. state: 'California',
  174. city: 'San Francisco',
  175. address: '3650 21st St, San Francisco',
  176. zip: 'CA 94114',
  177. },
  178. {
  179. name: 'Tyke',
  180. state: 'California',
  181. city: 'San Francisco',
  182. address: '3650 21st St, San Francisco',
  183. zip: 'CA 94114',
  184. },
  185. ],
  186. },
  187. {
  188. date: '2016-05-06',
  189. name: 'Tom',
  190. state: 'California',
  191. city: 'San Francisco',
  192. address: '3650 21st St, San Francisco',
  193. zip: 'CA 94114',
  194. family: [
  195. {
  196. name: 'Jerry',
  197. state: 'California',
  198. city: 'San Francisco',
  199. address: '3650 21st St, San Francisco',
  200. zip: 'CA 94114',
  201. },
  202. {
  203. name: 'Spike',
  204. state: 'California',
  205. city: 'San Francisco',
  206. address: '3650 21st St, San Francisco',
  207. zip: 'CA 94114',
  208. },
  209. {
  210. name: 'Tyke',
  211. state: 'California',
  212. city: 'San Francisco',
  213. address: '3650 21st St, San Francisco',
  214. zip: 'CA 94114',
  215. },
  216. ],
  217. },
  218. {
  219. date: '2016-05-07',
  220. name: 'Tom',
  221. state: 'California',
  222. city: 'San Francisco',
  223. address: '3650 21st St, San Francisco',
  224. zip: 'CA 94114',
  225. family: [
  226. {
  227. name: 'Jerry',
  228. state: 'California',
  229. city: 'San Francisco',
  230. address: '3650 21st St, San Francisco',
  231. zip: 'CA 94114',
  232. },
  233. {
  234. name: 'Spike',
  235. state: 'California',
  236. city: 'San Francisco',
  237. address: '3650 21st St, San Francisco',
  238. zip: 'CA 94114',
  239. },
  240. {
  241. name: 'Tyke',
  242. state: 'California',
  243. city: 'San Francisco',
  244. address: '3650 21st St, San Francisco',
  245. zip: 'CA 94114',
  246. },
  247. ],
  248. },
  249. ]
  250. </script>

树形数据与懒加载

支持树类型的数据的显示。 当 row 中包含 children 字段时,被视为树形数据。 渲染嵌套数据需要 prop 的 row-key。 此外,子行数据可以异步加载。 设置 Table 的lazy属性为 true 与加载函数 load 。 通过指定 row 中的hasChildren字段来指定哪些行是包含子节点。 childrenhasChildren都可以通过 tree-props 配置。

Table 表格 - 图17

  1. <template>
  2. <div>
  3. <el-table
  4. :data="tableData"
  5. style="width: 100%; margin-bottom: 20px"
  6. row-key="id"
  7. border
  8. default-expand-all
  9. >
  10. <el-table-column prop="date" label="date" sortable width="180" />
  11. <el-table-column prop="name" label="Name" sortable width="180" />
  12. </el-table>
  13. <el-table
  14. :data="tableData1"
  15. style="width: 100%"
  16. row-key="id"
  17. border
  18. lazy
  19. :load="load"
  20. :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
  21. >
  22. <el-table-column prop="date" label="Date" width="180" />
  23. <el-table-column prop="name" label="Name" width="180" />
  24. </el-table>
  25. </div>
  26. </template>
  27. <script lang="ts" setup>
  28. interface User {
  29. id: number
  30. date: string
  31. name: string
  32. hasChildren?: boolean
  33. children?: User[]
  34. }
  35. const load = (
  36. row: User,
  37. treeNode: unknown,
  38. resolve: (date: User[]) => void
  39. ) => {
  40. setTimeout(() => {
  41. resolve([
  42. {
  43. id: 31,
  44. date: '2016-05-01',
  45. name: 'wangxiaohu',
  46. },
  47. {
  48. id: 32,
  49. date: '2016-05-01',
  50. name: 'wangxiaohu',
  51. },
  52. ])
  53. }, 1000)
  54. }
  55. const tableData: User[] = [
  56. {
  57. id: 1,
  58. date: '2016-05-02',
  59. name: 'wangxiaohu',
  60. },
  61. {
  62. id: 2,
  63. date: '2016-05-04',
  64. name: 'wangxiaohu',
  65. },
  66. {
  67. id: 3,
  68. date: '2016-05-01',
  69. name: 'wangxiaohu',
  70. children: [
  71. {
  72. id: 31,
  73. date: '2016-05-01',
  74. name: 'wangxiaohu',
  75. },
  76. {
  77. id: 32,
  78. date: '2016-05-01',
  79. name: 'wangxiaohu',
  80. },
  81. ],
  82. },
  83. {
  84. id: 4,
  85. date: '2016-05-03',
  86. name: 'wangxiaohu',
  87. },
  88. ]
  89. const tableData1: User[] = [
  90. {
  91. id: 1,
  92. date: '2016-05-02',
  93. name: 'wangxiaohu',
  94. },
  95. {
  96. id: 2,
  97. date: '2016-05-04',
  98. name: 'wangxiaohu',
  99. },
  100. {
  101. id: 3,
  102. date: '2016-05-01',
  103. name: 'wangxiaohu',
  104. hasChildren: true,
  105. },
  106. {
  107. id: 4,
  108. date: '2016-05-03',
  109. name: 'wangxiaohu',
  110. },
  111. ]
  112. </script>

表尾合计行

若表格展示的是各类数字,可以在表尾显示各列的合计。

show-summary 设置为true就会在表格尾部展示合计行。 默认情况下,对于合计行,第一列不进行数据求合操作,而是显示「合计」二字(可通过sum-text配置),其余列会将本列所有数值进行求合操作,并显示出来。 当然,你也可以定义自己的合计逻辑。 使用 summary-method 并传入一个方法,返回一个数组,这个数组中的各项就会显示在合计行的各列中, 具体可以参考本例中的第二个表格。

Table 表格 - 图18

  1. <template>
  2. <el-table :data="tableData" border show-summary style="width: 100%">
  3. <el-table-column prop="id" label="ID" width="180" />
  4. <el-table-column prop="name" label="Name" />
  5. <el-table-column prop="amount1" sortable label="Amount 1" />
  6. <el-table-column prop="amount2" sortable label="Amount 2" />
  7. <el-table-column prop="amount3" sortable label="Amount 3" />
  8. </el-table>
  9. <el-table
  10. :data="tableData"
  11. border
  12. height="200"
  13. :summary-method="getSummaries"
  14. show-summary
  15. style="width: 100%; margin-top: 20px"
  16. >
  17. <el-table-column prop="id" label="ID" width="180" />
  18. <el-table-column prop="name" label="Name" />
  19. <el-table-column prop="amount1" label="Cost 1 ($)" />
  20. <el-table-column prop="amount2" label="Cost 2 ($)" />
  21. <el-table-column prop="amount3" label="Cost 3 ($)" />
  22. </el-table>
  23. </template>
  24. <script lang="ts" setup>
  25. import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
  26. interface Product {
  27. id: string
  28. name: string
  29. amount1: string
  30. amount2: string
  31. amount3: number
  32. }
  33. interface SummaryMethodProps<T = Product> {
  34. columns: TableColumnCtx<T>[]
  35. data: T[]
  36. }
  37. const getSummaries = (param: SummaryMethodProps) => {
  38. const { columns, data } = param
  39. const sums: string[] = []
  40. columns.forEach((column, index) => {
  41. if (index === 0) {
  42. sums[index] = 'Total Cost'
  43. return
  44. }
  45. const values = data.map((item) => Number(item[column.property]))
  46. if (!values.every((value) => Number.isNaN(value))) {
  47. sums[index] = `$ ${values.reduce((prev, curr) => {
  48. const value = Number(curr)
  49. if (!Number.isNaN(value)) {
  50. return prev + curr
  51. } else {
  52. return prev
  53. }
  54. }, 0)}`
  55. } else {
  56. sums[index] = 'N/A'
  57. }
  58. })
  59. return sums
  60. }
  61. const tableData: Product[] = [
  62. {
  63. id: '12987122',
  64. name: 'Tom',
  65. amount1: '234',
  66. amount2: '3.2',
  67. amount3: 10,
  68. },
  69. {
  70. id: '12987123',
  71. name: 'Tom',
  72. amount1: '165',
  73. amount2: '4.43',
  74. amount3: 12,
  75. },
  76. {
  77. id: '12987124',
  78. name: 'Tom',
  79. amount1: '324',
  80. amount2: '1.9',
  81. amount3: 9,
  82. },
  83. {
  84. id: '12987125',
  85. name: 'Tom',
  86. amount1: '621',
  87. amount2: '2.2',
  88. amount3: 17,
  89. },
  90. {
  91. id: '12987126',
  92. name: 'Tom',
  93. amount1: '539',
  94. amount2: '4.1',
  95. amount3: 15,
  96. },
  97. ]
  98. </script>

合并行或列

多行或多列共用一个数据时,可以合并行或列。

通过给 table 传入span-method方法可以实现合并行或列, 方法的参数是一个对象,里面包含当前行 row、当前列 column、当前行号 rowIndex、当前列号 columnIndex 四个属性。 该函数可以返回一个包含两个元素的数组,第一个元素代表 rowspan,第二个元素代表 colspan。 也可以返回一个键名为 rowspancolspan 的对象。

Table 表格 - 图19

  1. <template>
  2. <div>
  3. <el-table
  4. :data="tableData"
  5. :span-method="arraySpanMethod"
  6. border
  7. style="width: 100%"
  8. >
  9. <el-table-column prop="id" label="ID" width="180" />
  10. <el-table-column prop="name" label="Name" />
  11. <el-table-column prop="amount1" sortable label="Amount 1" />
  12. <el-table-column prop="amount2" sortable label="Amount 2" />
  13. <el-table-column prop="amount3" sortable label="Amount 3" />
  14. </el-table>
  15. <el-table
  16. :data="tableData"
  17. :span-method="objectSpanMethod"
  18. border
  19. style="width: 100%; margin-top: 20px"
  20. >
  21. <el-table-column prop="id" label="ID" width="180" />
  22. <el-table-column prop="name" label="Name" />
  23. <el-table-column prop="amount1" label="Amount 1" />
  24. <el-table-column prop="amount2" label="Amount 2" />
  25. <el-table-column prop="amount3" label="Amount 3" />
  26. </el-table>
  27. </div>
  28. </template>
  29. <script lang="ts" setup>
  30. import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
  31. interface User {
  32. id: string
  33. name: string
  34. amount1: string
  35. amount2: string
  36. amount3: number
  37. }
  38. interface SpanMethodProps {
  39. row: User
  40. column: TableColumnCtx<User>
  41. rowIndex: number
  42. columnIndex: number
  43. }
  44. const arraySpanMethod = ({
  45. row,
  46. column,
  47. rowIndex,
  48. columnIndex,
  49. }: SpanMethodProps) => {
  50. if (rowIndex % 2 === 0) {
  51. if (columnIndex === 0) {
  52. return [1, 2]
  53. } else if (columnIndex === 1) {
  54. return [0, 0]
  55. }
  56. }
  57. }
  58. const objectSpanMethod = ({
  59. row,
  60. column,
  61. rowIndex,
  62. columnIndex,
  63. }: SpanMethodProps) => {
  64. if (columnIndex === 0) {
  65. if (rowIndex % 2 === 0) {
  66. return {
  67. rowspan: 2,
  68. colspan: 1,
  69. }
  70. } else {
  71. return {
  72. rowspan: 0,
  73. colspan: 0,
  74. }
  75. }
  76. }
  77. }
  78. const tableData: User[] = [
  79. {
  80. id: '12987122',
  81. name: 'Tom',
  82. amount1: '234',
  83. amount2: '3.2',
  84. amount3: 10,
  85. },
  86. {
  87. id: '12987123',
  88. name: 'Tom',
  89. amount1: '165',
  90. amount2: '4.43',
  91. amount3: 12,
  92. },
  93. {
  94. id: '12987124',
  95. name: 'Tom',
  96. amount1: '324',
  97. amount2: '1.9',
  98. amount3: 9,
  99. },
  100. {
  101. id: '12987125',
  102. name: 'Tom',
  103. amount1: '621',
  104. amount2: '2.2',
  105. amount3: 17,
  106. },
  107. {
  108. id: '12987126',
  109. name: 'Tom',
  110. amount1: '539',
  111. amount2: '4.1',
  112. amount3: 15,
  113. },
  114. ]
  115. </script>

自定义索引

自定义 type=index 列的行号。

通过给 type=index 的列传入 index 属性,可以自定义索引。 该属性传入数字时,将作为索引的起始值。 也可以传入一个方法,它提供当前行的行号(从 0 开始)作为参数,返回值将作为索引展示。

Table 表格 - 图20

  1. <template>
  2. <el-table :data="tableData" style="width: 100%">
  3. <el-table-column type="index" :index="indexMethod" />
  4. <el-table-column prop="date" label="Date" width="180" />
  5. <el-table-column prop="name" label="Name" width="180" />
  6. <el-table-column prop="address" label="Address" />
  7. </el-table>
  8. </template>
  9. <script lang="ts" setup>
  10. const indexMethod = (index: number) => {
  11. return index * 2
  12. }
  13. const tableData = [
  14. {
  15. date: '2016-05-03',
  16. name: 'Tom',
  17. state: 'California',
  18. city: 'Los Angeles',
  19. address: 'No. 189, Grove St, Los Angeles',
  20. zip: 'CA 90036',
  21. tag: 'Home',
  22. },
  23. {
  24. date: '2016-05-02',
  25. name: 'Tom',
  26. state: 'California',
  27. city: 'Los Angeles',
  28. address: 'No. 189, Grove St, Los Angeles',
  29. zip: 'CA 90036',
  30. tag: 'Office',
  31. },
  32. {
  33. date: '2016-05-04',
  34. name: 'Tom',
  35. state: 'California',
  36. city: 'Los Angeles',
  37. address: 'No. 189, Grove St, Los Angeles',
  38. zip: 'CA 90036',
  39. tag: 'Home',
  40. },
  41. {
  42. date: '2016-05-01',
  43. name: 'Tom',
  44. state: 'California',
  45. city: 'Los Angeles',
  46. address: 'No. 189, Grove St, Los Angeles',
  47. zip: 'CA 90036',
  48. tag: 'Office',
  49. },
  50. ]
  51. </script>

表格布局

通过属性 table-layout Table 表格 - 图21 可以指定表格中单元格、行和列的布局方式

Table 表格 - 图22

  1. <template>
  2. <el-radio-group v-model="tableLayout">
  3. <el-radio-button label="fixed" />
  4. <el-radio-button label="auto" />
  5. </el-radio-group>
  6. <el-table :data="tableData" :table-layout="tableLayout">
  7. <el-table-column prop="date" label="Date" />
  8. <el-table-column prop="name" label="Name" />
  9. <el-table-column prop="address" label="Address" />
  10. </el-table>
  11. </template>
  12. <script lang="ts" setup>
  13. import { ref } from 'vue'
  14. const tableLayout = ref('fixed')
  15. const tableData = [
  16. {
  17. date: '2016-05-03',
  18. name: 'Tom',
  19. address: 'No. 189, Grove St, Los Angeles',
  20. },
  21. {
  22. date: '2016-05-02',
  23. name: 'Tom',
  24. address: 'No. 189, Grove St, Los Angeles',
  25. },
  26. {
  27. date: '2016-05-04',
  28. name: 'Tom',
  29. address: 'No. 189, Grove St, Los Angeles',
  30. },
  31. {
  32. date: '2016-05-01',
  33. name: 'Tom',
  34. address: 'No. 189, Grove St, Los Angeles',
  35. },
  36. ]
  37. </script>

Table 属性

属性说明类型可选值默认值
data显示的数据array
heightTable 的高度, 默认为自动高度。 如果 height 为 number 类型,单位 px;如果 height 为 string 类型,则这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。string / number
max-heightTable 的最大高度。 合法的值为数字或者单位为 px 的高度。string / number
stripe是否为斑马纹 tablebooleanfalse
border是否带有纵向边框booleanfalse
sizeTable 的尺寸stringlarge / default /small
fit列的宽度是否自撑开booleantrue
show-header是否显示表头booleantrue
highlight-current-row是否要高亮当前行booleanfalse
current-row-key当前行的 key,只写属性string / number
row-class-name行的 className 的回调方法,也可以使用字符串为所有行设置一个固定的 className。function({ row, rowIndex }) / string
row-style行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style。function({ row, rowIndex }) / object
cell-class-name单元格的 className 的回调方法,也可以使用字符串为所有单元格设置一个固定的 className。function({ row, column, rowIndex, columnIndex }) / string
cell-style单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style。function({ row, column, rowIndex, columnIndex }) / object
header-row-class-name表头行的 className 的回调方法,也可以使用字符串为所有表头行设置一个固定的 className。function({ row, rowIndex }) / string
header-row-style表头行的 style 的回调方法,也可以使用一个固定的 Object 为所有表头行设置一样的 Style。function({ row, rowIndex }) / object
header-cell-class-name表头单元格的 className 的回调方法,也可以使用字符串为所有表头单元格设置一个固定的 className。function({ row, column, rowIndex, columnIndex }) / string
header-cell-style表头单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style。function({ row, column, rowIndex, columnIndex }) / object
row-key行数据的 Key,用来优化 Table 的渲染; 在使用reserve-selection功能与显示树形数据时,该属性是必填的。 类型为 String 时,支持多层访问:user.info.id,但不支持 user.info[0].id,此种情况请使用 Functionfunction(row) / string
empty-text空数据时显示的文本内容, 也可以通过 #empty 设置stringNo Data
default-expand-all是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效booleanfalse
expand-row-keys可以通过该属性设置 Table 目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。array
default-sort默认的排序列的 prop 和顺序。 它的 prop 属性指定默认的排序的列,order 指定默认排序的顺序objectorder: ascending / descending如果只指定了 prop, 没有指定 order, 则默认顺序是 ascending
tooltip-effecttooltip effect 属性stringdark / lightdark
show-summary是否在表尾显示合计行booleanfalse
sum-text合计行第一列的文本string合计
summary-method自定义的合计计算方法function({ columns, data })
span-method合并行或列的计算方法function({ row, column, rowIndex, columnIndex })
select-on-indeterminate在多选表格中,当仅有部分行被选中时,点击表头的多选框时的行为。 若为 true,则选中所有行;若为 false,则取消选择所有行booleantrue
indent展示树形数据时,树节点的缩进number16
lazy是否懒加载子节点数据boolean
load加载子节点数据的函数,lazy 为 true 时生效,函数第二个参数包含了节点的层级信息function(row, treeNode, resolve)
tree-props渲染嵌套数据的配置选项object{ hasChildren: ‘hasChildren’, children: ‘children’ }
table-layout设置表格单元、行和列的布局方式stringfixed / autofixed
scrollbar-always-on总是显示滚动条booleanfalse
flexible 2.2.1确保主轴的最小尺寸booleanfalse

Table 事件

事件名说明回调参数
select当用户手动勾选数据行的 Checkbox 时触发的事件selection, row
select-all当用户手动勾选全选 Checkbox 时触发的事件selection
selection-change当选择项发生变化时会触发该事件selection
cell-mouse-enter当单元格 hover 进入时会触发该事件row, column, cell, event
cell-mouse-leave当单元格 hover 退出时会触发该事件row, column, cell, event
cell-click当某个单元格被点击时会触发该事件row, column, cell, event
cell-dblclick当某个单元格被双击击时会触发该事件row, column, cell, event
cell-contextmenu当某个单元格被鼠标右键点击时会触发该事件row, column, cell, event
row-click当某一行被点击时会触发该事件row, column, event
row-contextmenu当某一行被鼠标右键点击时会触发该事件row, column, event
row-dblclick当某一行被双击时会触发该事件row, column, event
header-click当某一列的表头被点击时会触发该事件column, event
header-contextmenu当某一列的表头被鼠标右键点击时触发该事件column, event
sort-change当表格的排序条件发生变化的时候会触发该事件{ column, prop, order }
filter-changecolumn 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件filters
current-change当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性currentRow, oldCurrentRow
header-dragend当拖动表头改变了列的宽度的时候会触发该事件newWidth, oldWidth, column, event
expand-change当用户对某一行展开或者关闭的时候会触发该事件(展开行时,回调的第二个参数为 expandedRows;树形表格时第二参数为 expanded)row, (expandedRows | expanded)

Table 方法

方法名说明参数
clearSelection用于多选表格,清空用户的选择
getSelectionRows返回当前选中的行
toggleRowSelection用于多选表格,切换某一行的选中状态, 如果使用了第二个参数,则可直接设置这一行选中与否row, selected
toggleAllSelection用于多选表格,切换全选和全不选
toggleRowExpansion用于可扩展的表格或树表格,如果某行被扩展,则切换。 使用第二个参数,您可以直接设置该行应该被扩展或折叠。row, expanded
setCurrentRow用于单选表格,设定某一行为选中行, 如果调用时不加参数,则会取消目前高亮行的选中状态。row
clearSort用于清空排序条件,数据会恢复成未排序的状态
clearFilter传入由columnKey 组成的数组以清除指定列的过滤条件。 如果没有参数,清除所有过滤器columnKeys
doLayout对 Table 进行重新布局。 当表格可见性变化时,您可能需要调用此方法以获得正确的布局
sort手动排序表格。 参数 prop 属性指定排序列,order 指定排序顺序。prop: string, order: string
scrollTo滚动到一组特定坐标(options: ScrollToOptions | number, yCoord?: number)
setScrollTop设置垂直滚动位置top
setScrollLeft设置水平滚动位置left

Table 插槽

插槽名说明子标签
-自定义默认内容Table-column
append插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。
empty当数据为空时自定义的内容

Table-column 属性

属性说明类型可选值默认值
type对应列的类型。 如果设置了selection则显示多选框; 如果设置了 index 则显示该行的索引(从 1 开始计算); 如果设置了 expand 则显示为一个可展开的按钮stringselection / index / expand
index如果设置了 type=index,可以通过传递 index 属性来自定义索引number / function(index)
labelcolumn 的 key,如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件string
column-keycolumn 的 key, column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件string
prop字段名称 对应列内容的字段名, 也可以使用 property属性string
width对应列的宽度string / number
min-width对应列的最小宽度, 对应列的最小宽度, 与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列string / number
fixed列是否固定在左侧或者右侧。 true 表示固定在左侧string / booleantrue / ‘left’ / ‘right’
render-header列标题 Label 区域渲染使用的 Functionfunction({ column, $index })
sortable对应列是否可以排序, 如果设置为 ‘custom’,则代表用户希望远程排序,需要监听 Table 的 sort-change 事件boolean / stringtrue / false / ‘custom’false
sort-method指定数据按照哪个属性进行排序,仅当sortable设置为true的时候有效。 应该如同 Array.sort 那样返回一个 Numberfunction(a, b)
sort-by指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。 如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推function(row, index) / string / array
sort-orders数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。 需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序array数组中的元素需为以下三者之一:ascending 表示升序,descending 表示降序,null 表示还原为原始顺序[‘ascending’, ‘descending’, null]
resizable对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)booleantrue
formatter用来格式化内容function(row, column, cellValue, index)
show-overflow-tooltip当内容过长被隐藏时显示 tooltipbooleanfalse
align对齐方式stringleft / center / rightleft
header-align表头对齐方式, 若不设置该项,则使用表格的对齐方式stringleft / center / right
class-name列的 classNamestring
label-class-name当前列标题的自定义类名string
selectable仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选function(row, index)
reserve-selection仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。booleanfalse
filters数据过滤的选项, 数组格式,数组中的元素需要有 text 和 value 属性。 数组中的每个元素都需要有 text 和 value 属性。array[{ text, value }]
filter-placement过滤弹出框的定位string与 Tooltip 的 placement 属性相同
filter-multiple数据过滤的选项是否多选booleantrue
filter-method数据过滤使用的方法, 如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示。function(value, row, column)
filtered-value选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。array

Table-column 插槽

插槽名说明
自定义列的内容 作用域参数为 { row, column, $index }
header自定义表头的内容, 作用域参数为 { column, $index }

常见问题解答(FAQ)

如何在表格中使用图像预览?

  1. <el-table-column label="Thumbnail" width="180">
  2. <template #default="scope">
  3. <div style="display: flex; align-items: center">
  4. <el-image :preview-src-list="srcList"/>
  5. </div>
  6. </template>
  7. </el-table-column>

注:由于固定列是通过 sticky 来实现的,如果表格中含有固定列,请在图像上添加 preview-teleported 属性。

当使用 DOM 模板时,为什么列没有渲染?

典型问题: #5046 Table 表格 - 图23 #5862 Table 表格 - 图24 #6919 Table 表格 - 图25

这是因为 HTML 定义只允许一些特定元素省略关闭标签,最常见的是 <input><img>。 对于任意其他元素,如果你省略了关闭标签,原生的 HTML 解析器会认为你从未关闭打开的标签。

详情请参阅 Vue 文档 Table 表格 - 图26

源代码

组件 Table 表格 - 图27 文档 Table 表格 - 图28

贡献者

Table 表格 - 图29 msidolphin

Table 表格 - 图30 三咲智子

Table 表格 - 图31 云游君

Table 表格 - 图32 JeremyWuuuuu

Table 表格 - 图33 qiang

Table 表格 - 图34 LIUCHAO

Table 表格 - 图35 zz

Table 表格 - 图36 Zhongxiang Wang

Table 表格 - 图37 Xc

Table 表格 - 图38 神楽坂みずき

Table 表格 - 图39 kooriookami

Table 表格 - 图40 Aex

Table 表格 - 图41 wiidede

Table 表格 - 图42 RealityBoy

Table 表格 - 图43 jarven

Table 表格 - 图44 Carter Li

Table 表格 - 图45 bqy_fe

Table 表格 - 图46 Alan Wang

Table 表格 - 图47 iamkun

Table 表格 - 图48 justwiner

Table 表格 - 图49 C.Y.Kun

Table 表格 - 图50 热爱vue的小菜鸟

Table 表格 - 图51 Jianjun Yu

Table 表格 - 图52 沐林森13

Table 表格 - 图53 joson

Table 表格 - 图54 Delyan Haralanov

Table 表格 - 图55 hminghe

Table 表格 - 图56 KAKI

Table 表格 - 图57 Yuyao Nie

Table 表格 - 图58 张仕春

Table 表格 - 图59 btea

Table 表格 - 图60 deepthan

Table 表格 - 图61 liu

Table 表格 - 图62 on the field of hope

Table 表格 - 图63 Ryan2128

Table 表格 - 图64 zazzaz

Table 表格 - 图65 Hades-li

Table 表格 - 图66 renovate[bot]

Table 表格 - 图67 liuyutao

Table 表格 - 图68 Chris

Table 表格 - 图69 류한경

Table 表格 - 图70 SongWuKong

Table 表格 - 图71 wanghaitao