rowspan.vue 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  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 rowSpanIndex = 0
  34. columns[rowSpanIndex].rowSpan = ({ rowIndex }) => (rowIndex % 2 === 0 && rowIndex <= data.length - 2 ? 2 : 1)
  35. const Row = ({ rowData, rowIndex, cells, columns }) => {
  36. const rowSpan = columns[rowSpanIndex].rowSpan({ rowData, rowIndex })
  37. if (rowSpan > 1) {
  38. const cell = cells[rowSpanIndex]
  39. const style = {
  40. ...cell.props.style,
  41. backgroundColor: 'var(--el-color-primary-light-3)',
  42. height: `${rowSpan * 50 - 1}px`,
  43. alignSelf: 'flex-start',
  44. zIndex: 1,
  45. }
  46. cells[rowSpanIndex] = cloneVNode(cell, { style })
  47. }
  48. return cells
  49. }
  50. </script>