colspan.vue 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <template>
  2. <el-table-v2 fixed :columns="columns" :data="data" :width="700" :height="400">
  3. <template #row="props">
  4. <Row v-bind="props" />
  5. </template>
  6. </el-table-v2>
  7. </template>
  8. <script lang="ts" setup>
  9. import { cloneVNode } from 'vue'
  10. const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
  11. Array.from({ length }).map((_, columnIndex) => ({
  12. ...props,
  13. key: `${prefix}${columnIndex}`,
  14. dataKey: `${prefix}${columnIndex}`,
  15. title: `Column ${columnIndex}`,
  16. width: 150,
  17. }))
  18. const generateData = (columns: ReturnType<typeof generateColumns>, length = 200, prefix = 'row-') =>
  19. Array.from({ length }).map((_, rowIndex) => {
  20. return columns.reduce(
  21. (rowData, column, columnIndex) => {
  22. rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
  23. return rowData
  24. },
  25. {
  26. id: `${prefix}${rowIndex}`,
  27. parentId: null,
  28. }
  29. )
  30. })
  31. const columns = generateColumns(10)
  32. const data = generateData(columns, 200)
  33. const colSpanIndex = 1
  34. columns[colSpanIndex].colSpan = ({ rowIndex }) => (rowIndex % 4) + 1
  35. columns[colSpanIndex].align = 'center'
  36. const Row = ({ rowData, rowIndex, cells, columns }) => {
  37. const colSpan = columns[colSpanIndex].colSpan({ rowData, rowIndex })
  38. if (colSpan > 1) {
  39. let width = Number.parseInt(cells[colSpanIndex].props.style.width)
  40. for (let i = 1; i < colSpan; i++) {
  41. width += Number.parseInt(cells[colSpanIndex + i].props.style.width)
  42. cells[colSpanIndex + i] = null
  43. }
  44. const style = {
  45. ...cells[colSpanIndex].props.style,
  46. width: `${width}px`,
  47. backgroundColor: 'var(--el-color-primary-light-3)',
  48. }
  49. cells[colSpanIndex] = cloneVNode(cells[colSpanIndex], { style })
  50. }
  51. return cells
  52. }
  53. </script>