selection.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <template>
  2. <div style="height: 400px">
  3. <el-auto-resizer>
  4. <template #default="{ height, width }">
  5. <el-table-v2
  6. :columns="columns"
  7. :data="data"
  8. :width="width"
  9. :height="height"
  10. fixed
  11. />
  12. </template>
  13. </el-auto-resizer>
  14. </div>
  15. </template>
  16. <script lang="tsx" setup>
  17. import { ref, unref } from 'vue'
  18. import { ElCheckbox } from 'element-plus'
  19. import type { FunctionalComponent } from 'vue'
  20. import type { CheckboxValueType, Column } from 'element-plus'
  21. type SelectionCellProps = {
  22. value: boolean
  23. intermediate?: boolean
  24. onChange: (value: CheckboxValueType) => void
  25. }
  26. const SelectionCell: FunctionalComponent<SelectionCellProps> = ({
  27. value,
  28. intermediate = false,
  29. onChange,
  30. }) => {
  31. return (
  32. <ElCheckbox
  33. onChange={onChange}
  34. modelValue={value}
  35. indeterminate={intermediate}
  36. />
  37. )
  38. }
  39. const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
  40. Array.from({ length }).map((_, columnIndex) => ({
  41. ...props,
  42. key: `${prefix}${columnIndex}`,
  43. dataKey: `${prefix}${columnIndex}`,
  44. title: `Column ${columnIndex}`,
  45. width: 150,
  46. }))
  47. const generateData = (
  48. columns: ReturnType<typeof generateColumns>,
  49. length = 200,
  50. prefix = 'row-'
  51. ) =>
  52. Array.from({ length }).map((_, rowIndex) => {
  53. return columns.reduce(
  54. (rowData, column, columnIndex) => {
  55. rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
  56. return rowData
  57. },
  58. {
  59. id: `${prefix}${rowIndex}`,
  60. checked: false,
  61. parentId: null,
  62. }
  63. )
  64. })
  65. const columns: Column<any>[] = generateColumns(10)
  66. columns.unshift({
  67. key: 'selection',
  68. width: 50,
  69. cellRenderer: ({ rowData }) => {
  70. const onChange = (value: CheckboxValueType) => (rowData.checked = value)
  71. return <SelectionCell value={rowData.checked} onChange={onChange} />
  72. },
  73. headerCellRenderer: () => {
  74. const _data = unref(data)
  75. const onChange = (value: CheckboxValueType) =>
  76. (data.value = _data.map((row) => {
  77. row.checked = value
  78. return row
  79. }))
  80. const allSelected = _data.every((row) => row.checked)
  81. const containsChecked = _data.some((row) => row.checked)
  82. return (
  83. <SelectionCell
  84. value={allSelected}
  85. intermediate={containsChecked && !allSelected}
  86. onChange={onChange}
  87. />
  88. )
  89. },
  90. })
  91. const data = ref(generateData(columns, 200))
  92. </script>