selection.vue 2.5 KB

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