sticky-rows.vue 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. <template>
  2. <el-table-v2 :columns="columns" :data="tableData" :fixed-data="fixedData" :width="700" :height="400" :row-class="rowClass" fixed @scroll="onScroll" />
  3. </template>
  4. <script lang="ts" setup>
  5. import { computed, ref } from 'vue'
  6. const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
  7. Array.from({ length }).map((_, columnIndex) => ({
  8. ...props,
  9. key: `${prefix}${columnIndex}`,
  10. dataKey: `${prefix}${columnIndex}`,
  11. title: `Column ${columnIndex}`,
  12. width: 150,
  13. }))
  14. const generateData = (columns: ReturnType<typeof generateColumns>, length = 200, prefix = 'row-') =>
  15. Array.from({ length }).map((_, rowIndex) => {
  16. return columns.reduce(
  17. (rowData, column, columnIndex) => {
  18. rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
  19. return rowData
  20. },
  21. {
  22. id: `${prefix}${rowIndex}`,
  23. parentId: null,
  24. }
  25. )
  26. })
  27. const columns = generateColumns(10)
  28. const data = generateData(columns, 200)
  29. const rowClass = ({ rowIndex }) => {
  30. if (rowIndex < 0 || (rowIndex + 1) % 5 === 0) return 'sticky-row'
  31. }
  32. const stickyIndex = ref(0)
  33. const fixedData = computed(() => data.slice(stickyIndex.value, stickyIndex.value + 1))
  34. const tableData = computed(() => {
  35. return data.slice(1)
  36. })
  37. const onScroll = ({ scrollTop }) => {
  38. stickyIndex.value = Math.floor(scrollTop / 250) * 5
  39. }
  40. </script>
  41. <style>
  42. .el-el-table-v2__fixed-header-row {
  43. background-color: var(--el-color-primary-light-5);
  44. font-weight: bold;
  45. }
  46. </style>