inline-editing.vue 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 { nextTick, ref, resolveDynamicComponent } from 'vue'
  12. import type { FunctionalComponent } from 'vue'
  13. import type { Column, ElInput } from 'element-plus'
  14. const Input = resolveDynamicComponent('ElInput') as typeof ElInput
  15. type SelectionCellProps = {
  16. value: string
  17. intermediate?: boolean
  18. onChange: (value: string) => void
  19. forwardRef: (el: InstanceType<typeof ElInput>) => void
  20. }
  21. const InputCell: FunctionalComponent<SelectionCellProps> = ({ value, onChange, forwardRef }) => {
  22. return <Input ref={forwardRef as any} onInput={onChange} modelValue={value} />
  23. }
  24. const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
  25. Array.from({ length }).map((_, columnIndex) => ({
  26. ...props,
  27. key: `${prefix}${columnIndex}`,
  28. dataKey: `${prefix}${columnIndex}`,
  29. title: `Column ${columnIndex}`,
  30. width: 150,
  31. }))
  32. const generateData = (columns: ReturnType<typeof generateColumns>, length = 200, prefix = 'row-') =>
  33. Array.from({ length }).map((_, rowIndex) => {
  34. return columns.reduce(
  35. (rowData, column, columnIndex) => {
  36. rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
  37. return rowData
  38. },
  39. {
  40. id: `${prefix}${rowIndex}`,
  41. editing: false,
  42. parentId: null,
  43. }
  44. )
  45. })
  46. const columns: Column<any>[] = generateColumns(10)
  47. columns[0] = {
  48. ...columns[0],
  49. title: 'Editable Column',
  50. cellRenderer: ({ rowData, column }) => {
  51. const onChange = (value: string) => {
  52. rowData[column.dataKey!] = value
  53. }
  54. const onEnterEditMode = () => {
  55. rowData.editing = true
  56. }
  57. const onExitEditMode = () => (rowData.editing = false)
  58. const input = ref()
  59. const setRef = el => {
  60. input.value = el
  61. if (el) {
  62. el.focus?.()
  63. }
  64. }
  65. return rowData.editing ? (
  66. <InputCell forwardRef={setRef} value={rowData[column.dataKey!]} onChange={onChange} onBlur={onExitEditMode} onKeydownEnter={onExitEditMode} />
  67. ) : (
  68. <div class="table-v2-inline-editing-trigger" onClick={onEnterEditMode}>
  69. {rowData[column.dataKey!]}
  70. </div>
  71. )
  72. },
  73. }
  74. const data = ref(generateData(columns, 200))
  75. </script>
  76. <style>
  77. .table-v2-inline-editing-trigger {
  78. border: 1px transparent dotted;
  79. padding: 4px;
  80. }
  81. .table-v2-inline-editing-trigger:hover {
  82. border-color: var(--el-color-primary);
  83. }
  84. </style>