grouping-header.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <el-table-v2 fixed :columns="fixedColumns" :data="data" :header-height="[50, 40, 50]" :header-class="headerClass" :width="700" :height="400">
  3. <template #header="props">
  4. <customized-header v-bind="props" />
  5. </template>
  6. </el-table-v2>
  7. </template>
  8. <script lang="tsx" setup>
  9. import { TableV2FixedDir, TableV2Placeholder } from 'element-plus'
  10. import type { FunctionalComponent } from 'vue'
  11. import type { HeaderClassNameGetter, TableV2CustomizedHeaderSlotParam } from 'element-plus'
  12. const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
  13. Array.from({ length }).map((_, columnIndex) => ({
  14. ...props,
  15. key: `${prefix}${columnIndex}`,
  16. dataKey: `${prefix}${columnIndex}`,
  17. title: `Column ${columnIndex}`,
  18. width: 150,
  19. }))
  20. const generateData = (columns: ReturnType<typeof generateColumns>, length = 200, prefix = 'row-') =>
  21. Array.from({ length }).map((_, rowIndex) => {
  22. return columns.reduce(
  23. (rowData, column, columnIndex) => {
  24. rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
  25. return rowData
  26. },
  27. {
  28. id: `${prefix}${rowIndex}`,
  29. parentId: null,
  30. }
  31. )
  32. })
  33. const columns = generateColumns(15)
  34. const data = generateData(columns, 200)
  35. const fixedColumns = columns.map((column, columnIndex) => {
  36. let fixed: TableV2FixedDir | undefined = undefined
  37. if (columnIndex < 3) fixed = TableV2FixedDir.LEFT
  38. if (columnIndex > 12) fixed = TableV2FixedDir.RIGHT
  39. return { ...column, fixed, width: 100 }
  40. })
  41. const CustomizedHeader: FunctionalComponent<TableV2CustomizedHeaderSlotParam> = ({ cells, columns, headerIndex }) => {
  42. if (headerIndex === 2) return cells
  43. const groupCells = [] as typeof cells
  44. let width = 0
  45. let idx = 0
  46. columns.forEach((column, columnIndex) => {
  47. if (column.placeholderSign === TableV2Placeholder) groupCells.push(cells[columnIndex])
  48. else {
  49. width += cells[columnIndex].props!.column.width
  50. idx++
  51. const nextColumn = columns[columnIndex + 1]
  52. if (columnIndex === columns.length - 1 || nextColumn.placeholderSign === TableV2Placeholder || idx === (headerIndex === 0 ? 4 : 2)) {
  53. groupCells.push(
  54. <div
  55. class="flex items-center justify-center custom-header-cell"
  56. style={{
  57. ...cells[columnIndex].props!.style,
  58. width: `${width}px`,
  59. }}
  60. >
  61. Group width {width}
  62. </div>
  63. )
  64. width = 0
  65. idx = 0
  66. }
  67. }
  68. })
  69. return groupCells
  70. }
  71. const headerClass = ({ headerIndex }: Parameters<HeaderClassNameGetter<any>>[0]) => {
  72. if (headerIndex === 1) return 'el-primary-color'
  73. return ''
  74. }
  75. </script>
  76. <style>
  77. .el-el-table-v2__header-row .custom-header-cell {
  78. border-right: 1px solid var(--el-border-color);
  79. }
  80. .el-el-table-v2__header-row .custom-header-cell:last-child {
  81. border-right: none;
  82. }
  83. .el-primary-color {
  84. background-color: var(--el-color-primary);
  85. color: var(--el-color-white);
  86. font-size: 14px;
  87. font-weight: bold;
  88. }
  89. .el-primary-color .custom-header-cell {
  90. padding: 0 4px;
  91. }
  92. </style>