vxe-table 4.19.0-beta.2 → 4.19.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +20 -20
  2. package/README.en.md +118 -118
  3. package/README.ja-JP.md +117 -117
  4. package/README.md +268 -268
  5. package/README.zh-TW.md +117 -117
  6. package/es/style.css +1 -1
  7. package/es/table/render/index.js +1 -1
  8. package/es/ui/index.js +1 -1
  9. package/es/ui/src/log.js +1 -1
  10. package/lib/index.umd.js +2767 -2851
  11. package/lib/index.umd.min.js +1 -1
  12. package/lib/style.css +1 -1
  13. package/lib/table/render/index.js +1 -1
  14. package/lib/table/render/index.min.js +1 -1
  15. package/lib/ui/index.js +1 -1
  16. package/lib/ui/index.min.js +1 -1
  17. package/lib/ui/src/log.js +1 -1
  18. package/lib/ui/src/log.min.js +1 -1
  19. package/package.json +92 -92
  20. package/packages/colgroup/index.ts +22 -22
  21. package/packages/column/index.ts +22 -22
  22. package/packages/components.ts +43 -43
  23. package/packages/grid/index.ts +18 -18
  24. package/packages/grid/src/emits.ts +19 -19
  25. package/packages/grid/src/grid.ts +1768 -1768
  26. package/packages/grid/src/props.ts +23 -23
  27. package/packages/index.ts +4 -4
  28. package/packages/locale/lang/ar-EG.ts +840 -840
  29. package/packages/locale/lang/de-DE.ts +840 -840
  30. package/packages/locale/lang/en-US.ts +840 -840
  31. package/packages/locale/lang/es-ES.ts +840 -840
  32. package/packages/locale/lang/fr-FR.ts +840 -840
  33. package/packages/locale/lang/hu-HU.ts +840 -840
  34. package/packages/locale/lang/hy-AM.ts +840 -840
  35. package/packages/locale/lang/id-ID.ts +840 -840
  36. package/packages/locale/lang/it-IT.ts +840 -840
  37. package/packages/locale/lang/ja-JP.ts +840 -840
  38. package/packages/locale/lang/ko-KR.ts +840 -840
  39. package/packages/locale/lang/ms-MY.ts +840 -840
  40. package/packages/locale/lang/nb-NO.ts +840 -840
  41. package/packages/locale/lang/pt-BR.ts +840 -840
  42. package/packages/locale/lang/ru-RU.ts +840 -840
  43. package/packages/locale/lang/th-TH.ts +840 -840
  44. package/packages/locale/lang/ug-CN.ts +840 -840
  45. package/packages/locale/lang/uk-UA.ts +840 -840
  46. package/packages/locale/lang/uz-UZ.ts +840 -840
  47. package/packages/locale/lang/vi-VN.ts +840 -840
  48. package/packages/locale/lang/zh-CHT.ts +840 -840
  49. package/packages/locale/lang/zh-CN.ts +840 -840
  50. package/packages/locale/lang/zh-HK.ts +3 -3
  51. package/packages/locale/lang/zh-MO.ts +3 -3
  52. package/packages/locale/lang/zh-TC.ts +3 -3
  53. package/packages/locale/lang/zh-TW.ts +3 -3
  54. package/packages/table/index.ts +26 -26
  55. package/packages/table/module/custom/hook.ts +422 -422
  56. package/packages/table/module/custom/panel.ts +1512 -1512
  57. package/packages/table/module/edit/hook.ts +1064 -1064
  58. package/packages/table/module/export/export-panel.ts +567 -567
  59. package/packages/table/module/export/hook.ts +1654 -1654
  60. package/packages/table/module/export/import-panel.ts +266 -266
  61. package/packages/table/module/export/util.ts +24 -24
  62. package/packages/table/module/filter/hook.ts +468 -468
  63. package/packages/table/module/filter/panel.ts +301 -301
  64. package/packages/table/module/keyboard/hook.ts +494 -494
  65. package/packages/table/module/menu/hook.ts +325 -325
  66. package/packages/table/module/menu/panel.ts +201 -201
  67. package/packages/table/module/validator/hook.ts +631 -631
  68. package/packages/table/render/index.ts +1440 -1440
  69. package/packages/table/src/body.ts +935 -935
  70. package/packages/table/src/cell.ts +1290 -1290
  71. package/packages/table/src/column.ts +190 -190
  72. package/packages/table/src/columnInfo.ts +225 -225
  73. package/packages/table/src/emits.ts +125 -125
  74. package/packages/table/src/footer.ts +368 -368
  75. package/packages/table/src/group.ts +59 -59
  76. package/packages/table/src/header.ts +561 -561
  77. package/packages/table/src/props.ts +324 -324
  78. package/packages/table/src/store.ts +14 -14
  79. package/packages/table/src/table.ts +14274 -14274
  80. package/packages/table/src/use/cell-view.ts +44 -44
  81. package/packages/table/src/use/index.ts +1 -1
  82. package/packages/table/src/util.ts +1086 -1086
  83. package/packages/toolbar/index.ts +18 -18
  84. package/packages/toolbar/src/toolbar.ts +701 -701
  85. package/packages/ui/index.ts +532 -532
  86. package/packages/ui/src/anime.ts +52 -52
  87. package/packages/ui/src/comp.ts +3 -3
  88. package/packages/ui/src/dom.ts +264 -264
  89. package/packages/ui/src/log.ts +8 -8
  90. package/packages/ui/src/utils.ts +56 -56
  91. package/packages/ui/src/vn.ts +55 -55
  92. package/packages/v-x-e-table/index.d.ts +4 -4
  93. package/packages/v-x-e-table/index.ts +4 -4
  94. package/styles/all.scss +7 -7
  95. package/styles/base.scss +16 -16
  96. package/styles/components/grid.scss +89 -89
  97. package/styles/components/icon.scss +225 -225
  98. package/styles/components/old-icon.scss +715 -715
  99. package/styles/components/table-module/all.scss +6 -6
  100. package/styles/components/table-module/custom.scss +550 -550
  101. package/styles/components/table-module/export.scss +130 -130
  102. package/styles/components/table-module/filter.scss +130 -130
  103. package/styles/components/table-module/menu.scss +81 -81
  104. package/styles/components/table.scss +2679 -2679
  105. package/styles/components/toolbar.scss +119 -119
  106. package/styles/default.scss +2 -2
  107. package/styles/helpers/baseMixin.scss +95 -95
  108. package/styles/index.scss +4 -4
  109. package/styles/modules.scss +5 -5
  110. package/styles/theme/base.scss +93 -93
  111. package/styles/theme/dark.scss +49 -49
  112. package/styles/theme/light.scss +44 -44
  113. package/styles/variable.scss +43 -43
  114. package/types/all.d.ts +37 -37
  115. package/types/index.d.ts +4 -4
  116. /package/es/{iconfont.1778157083004.ttf → iconfont.1778318183872.ttf} +0 -0
  117. /package/es/{iconfont.1778157083004.woff → iconfont.1778318183872.woff} +0 -0
  118. /package/es/{iconfont.1778157083004.woff2 → iconfont.1778318183872.woff2} +0 -0
  119. /package/lib/{iconfont.1778157083004.ttf → iconfont.1778318183872.ttf} +0 -0
  120. /package/lib/{iconfont.1778157083004.woff → iconfont.1778318183872.woff} +0 -0
  121. /package/lib/{iconfont.1778157083004.woff2 → iconfont.1778318183872.woff2} +0 -0
@@ -1,935 +1,935 @@
1
- import { h, ref, Ref, PropType, inject, nextTick, onMounted, onUnmounted } from 'vue'
2
- import { defineVxeComponent } from '../../ui/src/comp'
3
- import XEUtils from 'xe-utils'
4
- import { VxeUI } from '../../ui'
5
- import { getRowid, createHandleGetRowId, getCellRestHeight } from './util'
6
- import { updateCellTitle, getPropClass } from '../../ui/src/dom'
7
- import { isEnableConf } from '../../ui/src/utils'
8
- import { getSlotVNs } from '../../ui/src/vn'
9
-
10
- import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableDefines, VxeComponentSlotType } from '../../../types'
11
-
12
- const { getI18n, renderer, renderEmptyElement } = VxeUI
13
-
14
- const sourceType = 'table'
15
- const renderType = 'body'
16
-
17
- export default defineVxeComponent({
18
- name: 'VxeTableBody',
19
- props: {
20
- tableData: Array as PropType<any[]>,
21
- tableColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
22
- fixedColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
23
- fixedType: {
24
- type: String as PropType<'right' | 'left' | ''>,
25
- default: ''
26
- }
27
- },
28
- setup (props) {
29
- const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTablePrivateMethods)
30
-
31
- const { xID, props: tableProps, context: tableContext, reactData: tableReactData, internalData: tableInternalData } = $xeTable
32
- const { computeEditOpts, computeMouseOpts, computeCellOffsetWidth, computeAreaOpts, computeDefaultRowHeight, computeEmptyOpts, computeTooltipOpts, computeRadioOpts, computeExpandOpts, computeTreeOpts, computeCheckboxOpts, computeCellOpts, computeValidOpts, computeRowOpts, computeColumnOpts, computeRowDragOpts, computeResizableOpts, computeVirtualXOpts, computeVirtualYOpts, computeIsBodyRenderOptimize } = $xeTable.getComputeMaps()
33
-
34
- const refElem = ref() as Ref<HTMLDivElement>
35
- const refBodyScroll = ref() as Ref<HTMLDivElement>
36
- const refBodyTable = ref() as Ref<HTMLTableElement>
37
- const refBodyColgroup = ref() as Ref<HTMLTableColElement>
38
- const refBodyTBody = ref() as Ref<HTMLTableSectionElement>
39
- const refBodyXSpace = ref() as Ref<HTMLDivElement>
40
- const refBodyYSpace = ref() as Ref<HTMLDivElement>
41
- const refBodyEmptyBlock = ref() as Ref<HTMLDivElement>
42
-
43
- // 滚动、拖动过程中不需要触发
44
- const isVMScrollProcess = () => {
45
- const { delayHover } = tableProps
46
- const { isDragResize } = tableReactData
47
- const { lastSTime } = tableInternalData
48
- return !!(isDragResize || (lastSTime && Date.now() < lastSTime + (delayHover as number)))
49
- }
50
-
51
- const renderLine = (rowid: string, params: VxeTableDefines.CellRenderBodyParams, cellHeight: number): VxeComponentSlotType[] => {
52
- const { column } = params
53
- const { treeConfig } = tableProps
54
- const cellOpts = computeCellOpts.value
55
- const rowOpts = computeRowOpts.value
56
- const defaultRowHeight = computeDefaultRowHeight.value
57
- const treeOpts = computeTreeOpts.value
58
- const { slots, treeNode } = column
59
- const { fullAllDataRowIdData } = tableInternalData
60
- if (treeConfig && treeNode && (treeOpts.showLine || treeOpts.line)) {
61
- if (slots && (slots as any).line) {
62
- return $xeTable.callSlot((slots as any).line, params)
63
- }
64
- const rowRest = fullAllDataRowIdData[rowid]
65
- let rLevel = 0
66
- let prevRow = null
67
- let parentRow = null
68
- let lineHeight = ''
69
- if (rowRest) {
70
- rLevel = rowRest.level
71
- prevRow = rowRest.items[rowRest.treeIndex - 1]
72
- parentRow = rowRest.parent
73
- }
74
- if (!rLevel && !treeOpts.showRootLine) {
75
- return []
76
- }
77
- if (prevRow) {
78
- const prevRowRest = fullAllDataRowIdData[getRowid($xeTable, prevRow)] || {}
79
- lineHeight = `${prevRowRest.lineHeight || 0}px`
80
- } else if (rLevel && parentRow) {
81
- const parentRowRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)] || {}
82
- lineHeight = `calc(-1em + ${Math.floor(cellHeight / 2 + getCellRestHeight(parentRowRest, cellOpts, rowOpts, defaultRowHeight) / 2)}px)`
83
- }
84
- return [
85
- h('div', {
86
- key: 'tl',
87
- class: 'vxe-tree--line-wrapper'
88
- }, [
89
- h('div', {
90
- class: 'vxe-tree--line',
91
- style: {
92
- height: lineHeight,
93
- bottom: `-${Math.floor(cellHeight / 2)}px`,
94
- left: `calc(${(rLevel * treeOpts.indent)}px + 1em)`
95
- }
96
- })
97
- ])
98
- ]
99
- }
100
- return []
101
- }
102
-
103
- /**
104
- * 渲染列
105
- */
106
- const renderTdColumn = (
107
- seq: number | string,
108
- rowid: string,
109
- fixedType: 'left' | 'right' | '',
110
- isOptimizeMode: boolean,
111
- rowLevel: number,
112
- row: any,
113
- rowIndex: number,
114
- $rowIndex: number,
115
- _rowIndex: number,
116
- column: VxeTableDefines.ColumnInfo,
117
- $columnIndex: number,
118
- columns: VxeTableDefines.ColumnInfo[],
119
- items: any[]
120
- ) => {
121
- const $xeGrid = $xeTable.xeGrid
122
- const $xeGantt = $xeTable.xeGantt
123
-
124
- const { columnKey, resizable: allResizable, showOverflow: allShowOverflow, border, height, treeConfig, cellClassName: allCellClassName, cellStyle, align: allAlign, spanMethod, mouseConfig, editConfig, editRules, tooltipConfig, padding: allPadding } = tableProps
125
- const { tableData, tableColumn, dragRow, overflowX, overflowY, currentColumn, scrollXLoad, scrollYLoad, mergeBodyFlag, calcCellHeightFlag, resizeHeightFlag, resizeWidthFlag, editStore, isAllOverflow, validErrorMaps } = tableReactData
126
- const { fullAllDataRowIdData, fullColumnIdData, mergeBodyCellMaps, visibleColumn, afterFullData, mergeBodyList, scrollXStore, scrollYStore, keepUpdateFieldMaps } = tableInternalData
127
- const cellOpts = computeCellOpts.value
128
- const validOpts = computeValidOpts.value
129
- const checkboxOpts = computeCheckboxOpts.value
130
- const editOpts = computeEditOpts.value
131
- const tooltipOpts = computeTooltipOpts.value
132
- const resizableOpts = computeResizableOpts.value
133
- const virtualXOpts = computeVirtualXOpts.value
134
- const virtualYOpts = computeVirtualYOpts.value
135
- const { isAllColumnDrag, isAllRowDrag } = resizableOpts
136
- const rowOpts = computeRowOpts.value
137
- const rowDragOpts = computeRowDragOpts.value
138
- const defaultRowHeight = computeDefaultRowHeight.value
139
- const customCellHeight = calcCellHeightFlag ? (cellOpts.height || rowOpts.height) : 0
140
- const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = rowDragOpts
141
- const columnOpts = computeColumnOpts.value
142
- const mouseOpts = computeMouseOpts.value
143
- const areaOpts = computeAreaOpts.value
144
- const cellOffsetWidth = computeCellOffsetWidth.value
145
- const { selectCellToRow } = areaOpts
146
- const { field, type, cellRender, editRender, align, showOverflow, className, treeNode, rowResize, padding, verticalAlign, slots } = column
147
- const { verticalAlign: allVerticalAlign } = cellOpts
148
- const { actived } = editStore
149
- const rowRest = fullAllDataRowIdData[rowid] || {}
150
- const colid = column.id
151
- const colRest = fullColumnIdData[colid] || {}
152
- const renderOpts = editRender || cellRender
153
- const compConf = renderOpts ? renderer.get(renderOpts.name) : null
154
- const compCellClassName = compConf ? (compConf.tableCellClassName || compConf.cellClassName) : null
155
- const compCellStyle = compConf ? (compConf.tableCellStyle || compConf.cellStyle) : ''
156
- const showAllTip = tooltipOpts.showAll
157
- const columnIndex = colRest.index
158
- const _columnIndex = colRest._index
159
- const isEdit = isEnableConf(editRender)
160
- const resizeHeight = resizeHeightFlag ? rowRest.resizeHeight : 0
161
- let fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
162
- const isCellPadding = XEUtils.eqNull(padding) ? (allPadding === null ? cellOpts.padding : allPadding) : padding
163
- const cellOverflow = XEUtils.eqNull(showOverflow) ? allShowOverflow : showOverflow
164
- const showEllipsis = cellOverflow === 'ellipsis'
165
- const showTitle = cellOverflow === 'title'
166
- const showTooltip = cellOverflow === true || cellOverflow === 'tooltip'
167
- const hasEllipsis = isAllOverflow || showTitle || showTooltip || showEllipsis
168
- const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
169
- const isCsHeight = !!customCellHeight
170
- const isRsHeight = resizeHeight > 0
171
- let isDirty
172
- const tdOns: any = {}
173
- const cellAlign = align || (compConf ? compConf.tableCellAlign : '') || allAlign
174
- const cellVerticalAlign = XEUtils.eqNull(verticalAlign) ? allVerticalAlign : verticalAlign
175
- const errorValidItem = validErrorMaps[`${rowid}:${colid}`]
176
- const showValidTip = editRules && validOpts.showErrorMessage && (validOpts.message === 'default' ? (height || tableData.length > 1) : validOpts.message === 'inline')
177
- const tdAttrs: any = { colid }
178
- const cellParams: VxeTableDefines.CellRenderBodyParams & {
179
- $table: VxeTableConstructor<any> & VxeTablePrivateMethods
180
- } = {
181
- $table: $xeTable,
182
- $grid: $xeGrid,
183
- $gantt: $xeGantt,
184
- isEdit: false,
185
- seq,
186
- rowid,
187
- row,
188
- rowIndex,
189
- $rowIndex,
190
- _rowIndex,
191
- column,
192
- columnIndex,
193
- $columnIndex,
194
- _columnIndex,
195
- fixed: fixedType,
196
- source: sourceType,
197
- type: renderType,
198
- isHidden: !!fixedHiddenColumn,
199
- level: rowLevel,
200
- visibleData: afterFullData,
201
- data: tableData,
202
- items
203
- }
204
- let isRowDragCell = false
205
- let isDisabledDrag = false
206
- if (rowOpts.drag) {
207
- isRowDragCell = rowDragOpts.trigger === 'row' || (column.dragSort && rowDragOpts.trigger === 'cell')
208
- }
209
- if (isRowDragCell) {
210
- isDisabledDrag = !!(dragDisabledMethod && dragDisabledMethod(cellParams))
211
- }
212
- // hover 进入事件
213
- if (showTitle || showTooltip || showAllTip || tooltipConfig) {
214
- tdOns.onMouseover = (evnt: MouseEvent) => {
215
- if (!isVMScrollProcess()) {
216
- if (showTitle) {
217
- updateCellTitle(evnt.currentTarget, column)
218
- } else if (showTooltip || showAllTip) {
219
- // 如果配置了显示 tooltip
220
- $xeTable.triggerBodyTooltipEvent(evnt, cellParams)
221
- }
222
- }
223
- $xeTable.dispatchEvent('cell-mouseenter', Object.assign({ cell: evnt.currentTarget }, cellParams), evnt)
224
- }
225
- }
226
- // hover 退出事件
227
- if (showTooltip || showAllTip || tooltipConfig) {
228
- tdOns.onMouseleave = (evnt: MouseEvent) => {
229
- if (!isVMScrollProcess()) {
230
- if (showTooltip || showAllTip) {
231
- $xeTable.handleTargetLeaveEvent(evnt)
232
- }
233
- }
234
- $xeTable.dispatchEvent('cell-mouseleave', Object.assign({ cell: evnt.currentTarget }, cellParams), evnt)
235
- }
236
- }
237
- // 按下事件处理
238
- if (isRowDragCell || checkboxOpts.range || mouseConfig) {
239
- tdOns.onMousedown = (evnt: MouseEvent) => {
240
- $xeTable.triggerCellMousedownEvent(evnt, cellParams)
241
- }
242
- }
243
- // 拖拽列事件
244
- if (isRowDragCell) {
245
- tdOns.onMouseup = $xeTable.triggerCellMouseupEvent
246
- }
247
- // 点击事件处理
248
- tdOns.onClick = (evnt: MouseEvent) => {
249
- $xeTable.triggerCellClickEvent(evnt, cellParams)
250
- }
251
- // 双击事件处理
252
- tdOns.onDblclick = (evnt: MouseEvent) => {
253
- $xeTable.triggerCellDblclickEvent(evnt, cellParams)
254
- }
255
- let isMergeCell = false
256
- let mergeColspan = 1
257
- let mergeRowspan = 1
258
- // 合并行或列
259
- if (mergeBodyFlag && mergeBodyList.length) {
260
- const spanRest = mergeBodyCellMaps[`${_rowIndex}:${_columnIndex}`]
261
- if (spanRest) {
262
- const { rowspan, colspan } = spanRest
263
- if (!rowspan || !colspan) {
264
- return renderEmptyElement($xeTable)
265
- }
266
- if (rowspan > 1) {
267
- isMergeCell = true
268
- mergeRowspan = rowspan
269
- tdAttrs.rowspan = rowspan
270
- }
271
- if (colspan > 1) {
272
- isMergeCell = true
273
- mergeColspan = colspan
274
- tdAttrs.colspan = colspan
275
- }
276
- }
277
- } else if (spanMethod) {
278
- // 自定义合并行或列的方法
279
- const { rowspan = 1, colspan = 1 } = spanMethod(cellParams) || {}
280
- if (!rowspan || !colspan) {
281
- return renderEmptyElement($xeTable)
282
- }
283
- if (rowspan > 1) {
284
- isMergeCell = true
285
- mergeRowspan = rowspan
286
- tdAttrs.rowspan = rowspan
287
- }
288
- if (colspan > 1) {
289
- isMergeCell = true
290
- mergeColspan = colspan
291
- tdAttrs.colspan = colspan
292
- }
293
- }
294
- // 如果被合并不可隐藏
295
- if (fixedHiddenColumn && isMergeCell) {
296
- if (tdAttrs.colspan > 1 || tdAttrs.rowspan > 1) {
297
- fixedHiddenColumn = false
298
- }
299
- }
300
- // 如果编辑列开启显示状态
301
- if (!fixedHiddenColumn && editConfig && (editOpts.showStatus || editOpts.showUpdateStatus) && keepUpdateFieldMaps[field]) {
302
- isDirty = $xeTable.isUpdateByRow(row, field)
303
- }
304
-
305
- const isVNAutoHeight = !hasEllipsis && (scrollYLoad || scrollXLoad)
306
- let cellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight)
307
-
308
- const isLastColumn = $columnIndex === columns.length - 1
309
- const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
310
-
311
- let isVNPreEmptyStatus = false
312
- if (!isMergeCell) {
313
- if (!dragRow || getRowid($xeTable, dragRow) !== rowid) {
314
- if (overflowY && scrollYLoad && tableData.length > 16 && !treeConfig && !virtualYOpts.immediate && (_rowIndex < scrollYStore.visibleStartIndex - scrollYStore.preloadSize || _rowIndex > scrollYStore.visibleEndIndex + scrollYStore.preloadSize)) {
315
- isVNPreEmptyStatus = true
316
- } else if (overflowX && scrollXLoad && tableColumn.length > 10 && !virtualXOpts.immediate && !column.fixed && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
317
- isVNPreEmptyStatus = true
318
- }
319
- }
320
- }
321
-
322
- if (mergeRowspan > 1) {
323
- const mEndRow = afterFullData[_rowIndex + mergeRowspan - 1]
324
- if (mEndRow) {
325
- const meRowRest = fullAllDataRowIdData[getRowid($xeTable, mEndRow)]
326
- if (meRowRest) {
327
- cellHeight += meRowRest.oTop + getCellRestHeight(meRowRest, cellOpts, rowOpts, defaultRowHeight) - rowRest.oTop - getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight)
328
- }
329
- }
330
- }
331
-
332
- const tcStyle: Record<string, string> = {}
333
- if (hasEllipsis && resizeWidthFlag) {
334
- let mergeColWidth = 0
335
- if (mergeColspan > 1) {
336
- for (let index = 1; index < mergeColspan; index++) {
337
- const nextColumn = visibleColumn[columnIndex + index]
338
- if (nextColumn) {
339
- mergeColWidth += nextColumn.renderWidth
340
- }
341
- }
342
- }
343
- tcStyle.width = `${column.renderWidth + mergeColWidth - cellOffsetWidth}px`
344
- }
345
- if (scrollYLoad || scrollXLoad || hasEllipsis || isCsHeight || isRsHeight) {
346
- tcStyle.height = `${cellHeight}px`
347
- } else {
348
- tcStyle.minHeight = `${cellHeight}px`
349
- }
350
-
351
- const tdVNs: VxeComponentSlotType[] = []
352
- if (fixedHiddenColumn && isAllOverflow) {
353
- tdVNs.push(
354
- h('div', {
355
- key: 'tc',
356
- class: ['vxe-cell', {
357
- 'c--title': showTitle,
358
- 'c--tooltip': showTooltip,
359
- 'c--ellipsis': showEllipsis
360
- }],
361
- style: tcStyle
362
- })
363
- )
364
- } else {
365
- // 渲染单元格
366
- if (treeConfig) {
367
- tdVNs.push(...renderLine(rowid, cellParams, cellHeight))
368
- }
369
- const clVNs: VxeComponentSlotType[] = []
370
- if (!isVNPreEmptyStatus) {
371
- clVNs.push(
372
- h('div', {
373
- colid,
374
- rowid,
375
- class: 'vxe-cell--wrapper vxe-body-cell--wrapper'
376
- }, column.renderCell(cellParams))
377
- )
378
- }
379
- tdVNs.push(
380
- h('div', {
381
- key: 'tc',
382
- class: ['vxe-cell', {
383
- 'c--title': showTitle,
384
- 'c--tooltip': showTooltip,
385
- 'c--ellipsis': showEllipsis
386
- }],
387
- style: tcStyle,
388
- title: showTitle ? $xeTable.getCellLabel(row, column) : null
389
- }, clVNs)
390
- )
391
- if (showValidTip && errorValidItem) {
392
- const errRule = errorValidItem.rule
393
- const validSlot = slots ? slots.valid : null
394
- const validParams = { ...cellParams, ...errorValidItem, rule: errorValidItem }
395
- tdVNs.push(
396
- h('div', {
397
- key: 'tcv',
398
- class: ['vxe-cell--valid-error-tip', getPropClass(validOpts.className, validParams)],
399
- style: errRule && errRule.maxWidth
400
- ? {
401
- width: `${errRule.maxWidth}px`
402
- }
403
- : null
404
- }, [
405
- h('div', {
406
- class: `vxe-cell--valid-error-wrapper vxe-cell--valid-error-theme-${validOpts.theme || 'normal'}`
407
- }, [
408
- validSlot
409
- ? $xeTable.callSlot(validSlot, validParams)
410
- : [
411
- h('span', {
412
- class: 'vxe-cell--valid-error-msg'
413
- }, errorValidItem.content)
414
- ]
415
- ])
416
- ])
417
- )
418
- }
419
- }
420
-
421
- let showAreaRowStatus = false
422
- if (mouseConfig && mouseOpts.area && !_columnIndex && selectCellToRow) {
423
- showAreaRowStatus = true
424
- }
425
-
426
- if (!fixedHiddenColumn && showResizable && isAllColumnDrag) {
427
- tdVNs.push(
428
- h('div', {
429
- key: 'tcc',
430
- class: ['vxe-cell--col-resizable', {
431
- 'is--line': !border || border === 'none'
432
- }],
433
- onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
434
- onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
435
- })
436
- )
437
- }
438
-
439
- if ((rowResize || isAllRowDrag) && rowOpts.resizable) {
440
- tdVNs.push(
441
- h('div', {
442
- key: 'tcr',
443
- class: 'vxe-cell--row-resizable',
444
- onMousedown: (evnt: MouseEvent) => $xeTable.handleRowResizeMousedownEvent(evnt, cellParams),
445
- onDblclick: (evnt: MouseEvent) => $xeTable.handleRowResizeDblclickEvent(evnt, cellParams)
446
- })
447
- )
448
- }
449
-
450
- return h('td', {
451
- class: [
452
- 'vxe-table--column vxe-body--column',
453
- colid,
454
- cellVerticalAlign ? `col--vertical-${cellVerticalAlign}` : '',
455
- cellAlign ? `col--${cellAlign}` : '',
456
- type ? `col--${type}` : '',
457
- {
458
- 'col--last': isLastColumn,
459
- 'col--tree-node': treeNode,
460
- 'col--edit': isEdit,
461
- 'col--ellipsis': hasEllipsis,
462
- 'col--cs-height': isCsHeight,
463
- 'col--rs-height': isRsHeight,
464
- 'col--to-row': showAreaRowStatus,
465
- 'col--auto-height': isVNAutoHeight,
466
- 'fixed--width': !isAutoCellWidth,
467
- 'fixed--hidden': fixedHiddenColumn,
468
- 'is--padding': isCellPadding,
469
- 'is--progress': (fixedHiddenColumn && isAllOverflow) || isVNPreEmptyStatus,
470
- 'is--drag-cell': isRowDragCell && (isCrossDrag || isPeerDrag || !rowLevel),
471
- 'is--drag-disabled': isDisabledDrag,
472
- 'col--dirty': isDirty,
473
- 'col--active': editConfig && isEdit && (actived.row === row && (actived.column === column || editOpts.mode === 'row')),
474
- 'col--valid-error': !!errorValidItem,
475
- 'show--valid-bg': errorValidItem && validOpts.showErrorBackground,
476
- 'col--current': currentColumn === column
477
- },
478
- getPropClass(compCellClassName, cellParams),
479
- getPropClass(className, cellParams),
480
- getPropClass(allCellClassName, cellParams)
481
- ],
482
- key: columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || rowOpts.useKey || columnOpts.drag ? colid : $columnIndex,
483
- ...tdAttrs,
484
- style: Object.assign({}, XEUtils.isFunction(compCellStyle) ? compCellStyle(cellParams) : compCellStyle, XEUtils.isFunction(cellStyle) ? cellStyle(cellParams) : cellStyle),
485
- ...tdOns
486
- }, isOptimizeMode && fixedHiddenColumn ? [] : tdVNs)
487
- }
488
-
489
- const renderRows = (fixedType: 'left' | 'right' | '', isOptimizeMode: boolean, tableData: any[], tableColumn: VxeTableDefines.ColumnInfo[]) => {
490
- const $xeGrid = $xeTable.xeGrid
491
- const $xeGantt = $xeTable.xeGantt
492
-
493
- const { stripe, rowKey, highlightHoverRow, rowClassName, rowStyle, editConfig, treeConfig } = tableProps
494
- const { hasFixedColumn, treeExpandedFlag, scrollYLoad, isAllOverflow, rowExpandedFlag, expandColumn, selectRadioRow, pendingRowFlag, rowExpandHeightFlag, isRowGroupStatus } = tableReactData
495
- const { fullAllDataRowIdData, fullColumnIdData, treeExpandedMaps, pendingRowMaps, rowExpandedMaps, currentRow } = tableInternalData
496
- const checkboxOpts = computeCheckboxOpts.value
497
- const radioOpts = computeRadioOpts.value
498
- const treeOpts = computeTreeOpts.value
499
- const editOpts = computeEditOpts.value
500
- const rowOpts = computeRowOpts.value
501
- const columnOpts = computeColumnOpts.value
502
- const { transform, seqMode } = treeOpts
503
- const childrenField = treeOpts.children || treeOpts.childrenField
504
- const rows: any[] = []
505
- const { handleGetRowId } = createHandleGetRowId($xeTable)
506
- const isDeepRow = treeConfig || isRowGroupStatus
507
- tableData.forEach((row, $rowIndex) => {
508
- const rowid = handleGetRowId(row)
509
- const rowRest = fullAllDataRowIdData[rowid] || {}
510
- let rowIndex = $rowIndex
511
- let rowLevel = 0
512
- let seq: string | number = -1
513
- let _rowIndex = -1
514
- const hasRowGroupAggregate = isRowGroupStatus && row.isAggregate
515
- const trOn: Record<string, any> = {}
516
- // 当前行事件
517
- if (rowOpts.isHover || highlightHoverRow) {
518
- trOn.onMouseover = (evnt: MouseEvent) => {
519
- if (isVMScrollProcess()) {
520
- return
521
- }
522
- $xeTable.triggerHoverEvent(evnt, { row, rowIndex })
523
- }
524
- trOn.onMouseleave = () => {
525
- if (isVMScrollProcess()) {
526
- return
527
- }
528
- $xeTable.clearHoverRow()
529
- }
530
- }
531
- if (rowRest) {
532
- rowIndex = rowRest.index
533
- _rowIndex = rowRest._index
534
- rowLevel = rowRest.level
535
- seq = rowRest.seq
536
- if (hasRowGroupAggregate || (treeConfig && transform && seqMode === 'increasing')) {
537
- seq = rowRest._index + 1
538
- } else if ((treeConfig && seqMode === 'fixed')) {
539
- seq = rowRest._tIndex + 1
540
- }
541
- }
542
- const params = {
543
- $table: $xeTable,
544
- seq,
545
- rowid,
546
- fixed: fixedType,
547
- type: renderType,
548
- level: rowLevel,
549
- row,
550
- rowIndex,
551
- $rowIndex,
552
- _rowIndex
553
- }
554
- // 行是否被展开
555
- const isExpandRow = expandColumn && !!rowExpandedFlag && !!rowExpandedMaps[rowid]
556
- // 树节点是否被展开
557
- let isExpandTree = false
558
- let rowChildren = []
559
- let isNewRow = false
560
- if (editConfig) {
561
- isNewRow = $xeTable.isInsertByRow(row)
562
- }
563
- if (treeConfig && !scrollYLoad && !transform) {
564
- rowChildren = row[childrenField]
565
- isExpandTree = !!treeExpandedFlag && rowChildren && rowChildren.length > 0 && !!treeExpandedMaps[rowid]
566
- }
567
- // 拖拽行事件
568
- if (rowOpts.drag && !isRowGroupStatus && (!treeConfig || transform)) {
569
- trOn.onDragstart = $xeTable.handleRowDragDragstartEvent
570
- trOn.onDragend = $xeTable.handleRowDragDragendEvent
571
- trOn.onDragover = $xeTable.handleRowDragDragoverEvent
572
- }
573
- const trClass = [
574
- 'vxe-body--row',
575
- isDeepRow ? `row--level-${rowLevel}` : '',
576
- {
577
- 'row--stripe': stripe && (_rowIndex + 1) % 2 === 0,
578
- 'is--new': isNewRow,
579
- 'is--expand-row': isExpandRow,
580
- 'is--expand-tree': isExpandTree,
581
- 'row--new': isNewRow && (editOpts.showStatus || editOpts.showInsertStatus),
582
- 'row--radio': radioOpts.highlight && $xeTable.eqRow(selectRadioRow, row),
583
- 'row--checked': checkboxOpts.highlight && $xeTable.isCheckedByCheckboxRow(row),
584
- 'row--pending': !!pendingRowFlag && !!pendingRowMaps[rowid],
585
- 'row--group': hasRowGroupAggregate,
586
- 'row--current': currentRow && rowid === getRowid($xeTable, currentRow)
587
- },
588
- getPropClass(rowClassName, params)
589
- ]
590
- const tdVNs = tableColumn.map((column, $columnIndex) => {
591
- return renderTdColumn(seq, rowid, fixedType, isOptimizeMode, rowLevel, row, rowIndex, $rowIndex, _rowIndex, column, $columnIndex, tableColumn, tableData)
592
- })
593
- rows.push(
594
- h('tr', {
595
- class: trClass,
596
- rowid: rowid,
597
- style: rowStyle ? (XEUtils.isFunction(rowStyle) ? rowStyle(params) : rowStyle) : null,
598
- key: rowKey || rowOpts.useKey || rowOpts.drag || columnOpts.drag || isRowGroupStatus || treeConfig ? rowid : $rowIndex,
599
- ...trOn
600
- }, tdVNs)
601
- )
602
- // 如果行被展开了
603
- if (isExpandRow) {
604
- const expandOpts = computeExpandOpts.value
605
- const { height: expandHeight, padding, mode: expandMode } = expandOpts
606
- if (expandMode === 'fixed') {
607
- const currExpHeight = rowRest.expandHeight
608
- let expHeight = 0
609
- if (rowExpandHeightFlag) {
610
- if (currExpHeight || expandHeight) {
611
- expHeight = (currExpHeight || expandHeight || 0) + 1
612
- }
613
- }
614
- rows.push(
615
- h('tr', {
616
- class: 'vxe-body--row-expanded-place',
617
- key: `expand_${rowid}`,
618
- rowid
619
- }, [
620
- h('td', {
621
- class: 'vxe-body--row-expanded-place-column',
622
- colspan: tableColumn.length,
623
- style: {
624
- height: `${expHeight}px`
625
- }
626
- })
627
- ])
628
- )
629
- } else {
630
- const cellStyle: any = {}
631
- if (expandHeight) {
632
- cellStyle.height = `${expandHeight}px`
633
- }
634
- if (treeConfig) {
635
- cellStyle.paddingLeft = `${(rowLevel * treeOpts.indent) + 30}px`
636
- }
637
- const { showOverflow } = expandColumn || {}
638
- const colid = expandColumn.id
639
- const colRest = fullColumnIdData[colid] || {}
640
- const hasEllipsis = XEUtils.eqNull(showOverflow) ? isAllOverflow : showOverflow
641
- let columnIndex = -1
642
- let $columnIndex = -1
643
- let _columnIndex = -1
644
- if (colRest) {
645
- columnIndex = colRest.index
646
- $columnIndex = colRest.$index
647
- _columnIndex = colRest._index
648
- }
649
- const expandParams: VxeTableDefines.CellRenderDataParams = {
650
- $table: $xeTable,
651
- $grid: $xeGrid,
652
- $gantt: $xeGantt,
653
- seq,
654
- column: expandColumn as VxeTableDefines.ColumnInfo,
655
- columnIndex,
656
- $columnIndex,
657
- _columnIndex,
658
- fixed: fixedType,
659
- source: sourceType,
660
- type: renderType,
661
- level: rowLevel,
662
- row,
663
- rowid,
664
- rowIndex,
665
- $rowIndex,
666
- _rowIndex,
667
- isHidden: false,
668
- isEdit: false,
669
- visibleData: [],
670
- data: [],
671
- items: []
672
- }
673
- rows.push(
674
- h('tr', {
675
- class: ['vxe-body--expanded-row', {
676
- 'is--padding': padding
677
- }],
678
- key: `expand_${rowid}`
679
- }, [
680
- h('td', {
681
- class: ['vxe-body--expanded-column', {
682
- 'fixed--hidden': fixedType && !hasFixedColumn,
683
- 'col--ellipsis': hasEllipsis
684
- }],
685
- colspan: tableColumn.length
686
- }, [
687
- h('div', {
688
- class: ['vxe-body--expanded-cell', {
689
- 'is--ellipsis': expandHeight
690
- }],
691
- style: cellStyle
692
- }, [
693
- expandColumn.renderData(expandParams)
694
- ])
695
- ])
696
- ])
697
- )
698
- }
699
- }
700
- // 如果是树形表格
701
- if (isExpandTree) {
702
- rows.push(...renderRows(fixedType, isOptimizeMode, rowChildren, tableColumn))
703
- }
704
- })
705
- return rows
706
- }
707
-
708
- onMounted(() => {
709
- nextTick(() => {
710
- const { fixedType } = props
711
- const { elemStore } = tableInternalData
712
- const prefix = `${fixedType || 'main'}-body-`
713
- elemStore[`${prefix}wrapper`] = refElem
714
- elemStore[`${prefix}scroll`] = refBodyScroll
715
- elemStore[`${prefix}table`] = refBodyTable
716
- elemStore[`${prefix}colgroup`] = refBodyColgroup
717
- elemStore[`${prefix}list`] = refBodyTBody
718
- elemStore[`${prefix}xSpace`] = refBodyXSpace
719
- elemStore[`${prefix}ySpace`] = refBodyYSpace
720
- elemStore[`${prefix}emptyBlock`] = refBodyEmptyBlock
721
- })
722
- })
723
-
724
- onUnmounted(() => {
725
- const { fixedType } = props
726
- const { elemStore } = tableInternalData
727
- const prefix = `${fixedType || 'main'}-body-`
728
- elemStore[`${prefix}wrapper`] = null
729
- elemStore[`${prefix}scroll`] = null
730
- elemStore[`${prefix}table`] = null
731
- elemStore[`${prefix}colgroup`] = null
732
- elemStore[`${prefix}list`] = null
733
- elemStore[`${prefix}xSpace`] = null
734
- elemStore[`${prefix}ySpace`] = null
735
- elemStore[`${prefix}emptyBlock`] = null
736
- })
737
-
738
- const renderVN = () => {
739
- const { slots } = tableContext
740
- const $xeGrid = $xeTable.xeGrid
741
- const $xeGantt = $xeTable.xeGantt
742
-
743
- const { fixedColumn, fixedType, tableColumn } = props
744
- const { mouseConfig } = tableProps
745
- const { isGroup, tableData, isColLoading, overflowX, scrollXLoad, scrollYLoad, dragRow, dragCol } = tableReactData
746
- const { visibleColumn, fullAllDataRowIdData, fullColumnIdData } = tableInternalData
747
- const emptyOpts = computeEmptyOpts.value
748
- const mouseOpts = computeMouseOpts.value
749
- const isBodyRenderOptimize = computeIsBodyRenderOptimize.value
750
-
751
- let renderDataList = tableData
752
- let renderColumnList = tableColumn as VxeTableDefines.ColumnInfo[]
753
- const isOptimizeMode = isBodyRenderOptimize
754
-
755
- if (!isColLoading && (fixedType || !overflowX)) {
756
- renderColumnList = visibleColumn
757
- }
758
-
759
- if (fixedType) {
760
- if (isOptimizeMode) {
761
- renderColumnList = fixedColumn || []
762
- }
763
- }
764
-
765
- // 行拖拽
766
- if (scrollYLoad && dragRow) {
767
- if (renderDataList.length > 2) {
768
- const dRowRest = fullAllDataRowIdData[getRowid($xeTable, dragRow)]
769
- if (dRowRest) {
770
- const drIndex = dRowRest._index
771
- const firstRow = renderDataList[0]
772
- const lastRow = renderDataList[renderDataList.length - 1]
773
- const firstRowRest = fullAllDataRowIdData[getRowid($xeTable, firstRow)]
774
- const lastRowRest = fullAllDataRowIdData[getRowid($xeTable, lastRow)]
775
- if (firstRowRest && lastRowRest) {
776
- const frIndex = firstRowRest._index
777
- const lrIndex = lastRowRest._index
778
- if (drIndex < frIndex) {
779
- renderDataList = [dragRow].concat(renderDataList)
780
- } else if (drIndex > lrIndex) {
781
- renderDataList = renderDataList.concat([dragRow])
782
- }
783
- }
784
- }
785
- }
786
- }
787
-
788
- if (!fixedType && !isGroup) {
789
- // 列拖拽
790
- if (scrollXLoad && dragCol) {
791
- if (renderColumnList.length > 2) {
792
- const dCowRest = fullColumnIdData[dragCol.id]
793
- if (dCowRest) {
794
- const dcIndex = dCowRest._index
795
- const firstCol = renderColumnList[0]
796
- const lastCol = renderColumnList[renderColumnList.length - 1]
797
- const firstColRest = fullColumnIdData[firstCol.id]
798
- const lastColRest = fullColumnIdData[lastCol.id]
799
- if (firstColRest && lastColRest) {
800
- const fcIndex = firstColRest._index
801
- const lcIndex = lastColRest._index
802
- if (dcIndex < fcIndex) {
803
- renderColumnList = [dragCol].concat(renderColumnList)
804
- } else if (dcIndex > lcIndex) {
805
- renderColumnList = renderColumnList.concat([dragCol])
806
- }
807
- }
808
- }
809
- }
810
- }
811
- }
812
-
813
- let emptyContent: string | VxeComponentSlotType | VxeComponentSlotType[]
814
- const emptySlot = slots ? slots.empty : null
815
- const emptyParams = { $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }
816
- if (emptySlot) {
817
- emptyContent = $xeTable.callSlot(emptySlot, emptyParams)
818
- } else {
819
- const compConf = emptyOpts.name ? renderer.get(emptyOpts.name) : null
820
- const rtEmptyView = compConf ? (compConf.renderTableEmpty || compConf.renderTableEmptyView || compConf.renderEmpty) : null
821
- if (rtEmptyView) {
822
- emptyContent = getSlotVNs(rtEmptyView(emptyOpts, emptyParams))
823
- } else {
824
- emptyContent = tableProps.emptyText || getI18n('vxe.table.emptyText')
825
- }
826
- }
827
-
828
- return h('div', {
829
- ref: refElem,
830
- class: ['vxe-table--body-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
831
- xid: xID
832
- }, [
833
- h('div', {
834
- ref: refBodyScroll,
835
- class: 'vxe-table--body-inner-wrapper',
836
- onScroll (evnt) {
837
- $xeTable.triggerBodyScrollEvent(evnt, fixedType)
838
- }
839
- }, [
840
- fixedType
841
- ? renderEmptyElement($xeTable)
842
- : h('div', {
843
- ref: refBodyXSpace,
844
- class: 'vxe-body--x-space'
845
- }),
846
- h('div', {
847
- ref: refBodyYSpace,
848
- class: 'vxe-body--y-space'
849
- }),
850
- h('table', {
851
- ref: refBodyTable,
852
- class: 'vxe-table--body',
853
- xid: xID,
854
- cellspacing: 0,
855
- cellpadding: 0,
856
- border: 0,
857
- xvm: isOptimizeMode ? '1' : null
858
- }, [
859
- /**
860
- * 列宽
861
- */
862
- h('colgroup', {
863
- ref: refBodyColgroup
864
- }, renderColumnList.map((column, $columnIndex) => {
865
- return h('col', {
866
- name: column.id,
867
- key: $columnIndex,
868
- style: {
869
- width: `${column.renderWidth}px`
870
- }
871
- })
872
- })),
873
- /**
874
- * 内容
875
- */
876
- h('tbody', {
877
- ref: refBodyTBody
878
- }, renderRows(fixedType, isOptimizeMode, renderDataList, renderColumnList))
879
- ]),
880
- h('div', {
881
- class: 'vxe-table--checkbox-range'
882
- }),
883
- mouseConfig && mouseOpts.area
884
- ? h('div', {
885
- class: 'vxe-table--cell-area',
886
- xid: xID
887
- }, [
888
- h('span', {
889
- class: 'vxe-table--cell-main-area'
890
- }, mouseOpts.extension
891
- ? [
892
- h('span', {
893
- class: 'vxe-table--cell-main-area-btn',
894
- onMousedown (evnt: MouseEvent) {
895
- if ($xeTable.triggerCellAreaExtendMousedownEvent) {
896
- $xeTable.triggerCellAreaExtendMousedownEvent(evnt, { $table: $xeTable, fixed: fixedType, type: renderType })
897
- }
898
- }
899
- })
900
- ]
901
- : []),
902
- h('span', {
903
- class: 'vxe-table--cell-clip-area'
904
- }),
905
- h('span', {
906
- class: 'vxe-table--cell-extend-area'
907
- }),
908
- h('span', {
909
- class: 'vxe-table--cell-multi-area'
910
- }),
911
- h('span', {
912
- class: 'vxe-table--cell-active-area'
913
- }),
914
- h('span', {
915
- class: 'vxe-table--cell-row-status-area'
916
- })
917
- ])
918
- : renderEmptyElement($xeTable),
919
- !fixedType
920
- ? h('div', {
921
- class: 'vxe-table--empty-block',
922
- ref: refBodyEmptyBlock
923
- }, [
924
- h('div', {
925
- class: 'vxe-table--empty-content'
926
- }, emptyContent)
927
- ])
928
- : renderEmptyElement($xeTable)
929
- ])
930
- ])
931
- }
932
-
933
- return renderVN
934
- }
935
- })
1
+ import { h, ref, Ref, PropType, inject, nextTick, onMounted, onUnmounted } from 'vue'
2
+ import { defineVxeComponent } from '../../ui/src/comp'
3
+ import XEUtils from 'xe-utils'
4
+ import { VxeUI } from '../../ui'
5
+ import { getRowid, createHandleGetRowId, getCellRestHeight } from './util'
6
+ import { updateCellTitle, getPropClass } from '../../ui/src/dom'
7
+ import { isEnableConf } from '../../ui/src/utils'
8
+ import { getSlotVNs } from '../../ui/src/vn'
9
+
10
+ import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableDefines, VxeComponentSlotType } from '../../../types'
11
+
12
+ const { getI18n, renderer, renderEmptyElement } = VxeUI
13
+
14
+ const sourceType = 'table'
15
+ const renderType = 'body'
16
+
17
+ export default defineVxeComponent({
18
+ name: 'VxeTableBody',
19
+ props: {
20
+ tableData: Array as PropType<any[]>,
21
+ tableColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
22
+ fixedColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
23
+ fixedType: {
24
+ type: String as PropType<'right' | 'left' | ''>,
25
+ default: ''
26
+ }
27
+ },
28
+ setup (props) {
29
+ const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTablePrivateMethods)
30
+
31
+ const { xID, props: tableProps, context: tableContext, reactData: tableReactData, internalData: tableInternalData } = $xeTable
32
+ const { computeEditOpts, computeMouseOpts, computeCellOffsetWidth, computeAreaOpts, computeDefaultRowHeight, computeEmptyOpts, computeTooltipOpts, computeRadioOpts, computeExpandOpts, computeTreeOpts, computeCheckboxOpts, computeCellOpts, computeValidOpts, computeRowOpts, computeColumnOpts, computeRowDragOpts, computeResizableOpts, computeVirtualXOpts, computeVirtualYOpts, computeIsBodyRenderOptimize } = $xeTable.getComputeMaps()
33
+
34
+ const refElem = ref() as Ref<HTMLDivElement>
35
+ const refBodyScroll = ref() as Ref<HTMLDivElement>
36
+ const refBodyTable = ref() as Ref<HTMLTableElement>
37
+ const refBodyColgroup = ref() as Ref<HTMLTableColElement>
38
+ const refBodyTBody = ref() as Ref<HTMLTableSectionElement>
39
+ const refBodyXSpace = ref() as Ref<HTMLDivElement>
40
+ const refBodyYSpace = ref() as Ref<HTMLDivElement>
41
+ const refBodyEmptyBlock = ref() as Ref<HTMLDivElement>
42
+
43
+ // 滚动、拖动过程中不需要触发
44
+ const isVMScrollProcess = () => {
45
+ const { delayHover } = tableProps
46
+ const { isDragResize } = tableReactData
47
+ const { lastSTime } = tableInternalData
48
+ return !!(isDragResize || (lastSTime && Date.now() < lastSTime + (delayHover as number)))
49
+ }
50
+
51
+ const renderLine = (rowid: string, params: VxeTableDefines.CellRenderBodyParams, cellHeight: number): VxeComponentSlotType[] => {
52
+ const { column } = params
53
+ const { treeConfig } = tableProps
54
+ const cellOpts = computeCellOpts.value
55
+ const rowOpts = computeRowOpts.value
56
+ const defaultRowHeight = computeDefaultRowHeight.value
57
+ const treeOpts = computeTreeOpts.value
58
+ const { slots, treeNode } = column
59
+ const { fullAllDataRowIdData } = tableInternalData
60
+ if (treeConfig && treeNode && (treeOpts.showLine || treeOpts.line)) {
61
+ if (slots && (slots as any).line) {
62
+ return $xeTable.callSlot((slots as any).line, params)
63
+ }
64
+ const rowRest = fullAllDataRowIdData[rowid]
65
+ let rLevel = 0
66
+ let prevRow = null
67
+ let parentRow = null
68
+ let lineHeight = ''
69
+ if (rowRest) {
70
+ rLevel = rowRest.level
71
+ prevRow = rowRest.items[rowRest.treeIndex - 1]
72
+ parentRow = rowRest.parent
73
+ }
74
+ if (!rLevel && !treeOpts.showRootLine) {
75
+ return []
76
+ }
77
+ if (prevRow) {
78
+ const prevRowRest = fullAllDataRowIdData[getRowid($xeTable, prevRow)] || {}
79
+ lineHeight = `${prevRowRest.lineHeight || 0}px`
80
+ } else if (rLevel && parentRow) {
81
+ const parentRowRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)] || {}
82
+ lineHeight = `calc(-1em + ${Math.floor(cellHeight / 2 + getCellRestHeight(parentRowRest, cellOpts, rowOpts, defaultRowHeight) / 2)}px)`
83
+ }
84
+ return [
85
+ h('div', {
86
+ key: 'tl',
87
+ class: 'vxe-tree--line-wrapper'
88
+ }, [
89
+ h('div', {
90
+ class: 'vxe-tree--line',
91
+ style: {
92
+ height: lineHeight,
93
+ bottom: `-${Math.floor(cellHeight / 2)}px`,
94
+ left: `calc(${(rLevel * treeOpts.indent)}px + 1em)`
95
+ }
96
+ })
97
+ ])
98
+ ]
99
+ }
100
+ return []
101
+ }
102
+
103
+ /**
104
+ * 渲染列
105
+ */
106
+ const renderTdColumn = (
107
+ seq: number | string,
108
+ rowid: string,
109
+ fixedType: 'left' | 'right' | '',
110
+ isOptimizeMode: boolean,
111
+ rowLevel: number,
112
+ row: any,
113
+ rowIndex: number,
114
+ $rowIndex: number,
115
+ _rowIndex: number,
116
+ column: VxeTableDefines.ColumnInfo,
117
+ $columnIndex: number,
118
+ columns: VxeTableDefines.ColumnInfo[],
119
+ items: any[]
120
+ ) => {
121
+ const $xeGrid = $xeTable.xeGrid
122
+ const $xeGantt = $xeTable.xeGantt
123
+
124
+ const { columnKey, resizable: allResizable, showOverflow: allShowOverflow, border, height, treeConfig, cellClassName: allCellClassName, cellStyle, align: allAlign, spanMethod, mouseConfig, editConfig, editRules, tooltipConfig, padding: allPadding } = tableProps
125
+ const { tableData, tableColumn, dragRow, overflowX, overflowY, currentColumn, scrollXLoad, scrollYLoad, mergeBodyFlag, calcCellHeightFlag, resizeHeightFlag, resizeWidthFlag, editStore, isAllOverflow, validErrorMaps } = tableReactData
126
+ const { fullAllDataRowIdData, fullColumnIdData, mergeBodyCellMaps, visibleColumn, afterFullData, mergeBodyList, scrollXStore, scrollYStore, keepUpdateFieldMaps } = tableInternalData
127
+ const cellOpts = computeCellOpts.value
128
+ const validOpts = computeValidOpts.value
129
+ const checkboxOpts = computeCheckboxOpts.value
130
+ const editOpts = computeEditOpts.value
131
+ const tooltipOpts = computeTooltipOpts.value
132
+ const resizableOpts = computeResizableOpts.value
133
+ const virtualXOpts = computeVirtualXOpts.value
134
+ const virtualYOpts = computeVirtualYOpts.value
135
+ const { isAllColumnDrag, isAllRowDrag } = resizableOpts
136
+ const rowOpts = computeRowOpts.value
137
+ const rowDragOpts = computeRowDragOpts.value
138
+ const defaultRowHeight = computeDefaultRowHeight.value
139
+ const customCellHeight = calcCellHeightFlag ? (cellOpts.height || rowOpts.height) : 0
140
+ const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = rowDragOpts
141
+ const columnOpts = computeColumnOpts.value
142
+ const mouseOpts = computeMouseOpts.value
143
+ const areaOpts = computeAreaOpts.value
144
+ const cellOffsetWidth = computeCellOffsetWidth.value
145
+ const { selectCellToRow } = areaOpts
146
+ const { field, type, cellRender, editRender, align, showOverflow, className, treeNode, rowResize, padding, verticalAlign, slots } = column
147
+ const { verticalAlign: allVerticalAlign } = cellOpts
148
+ const { actived } = editStore
149
+ const rowRest = fullAllDataRowIdData[rowid] || {}
150
+ const colid = column.id
151
+ const colRest = fullColumnIdData[colid] || {}
152
+ const renderOpts = editRender || cellRender
153
+ const compConf = renderOpts ? renderer.get(renderOpts.name) : null
154
+ const compCellClassName = compConf ? (compConf.tableCellClassName || compConf.cellClassName) : null
155
+ const compCellStyle = compConf ? (compConf.tableCellStyle || compConf.cellStyle) : ''
156
+ const showAllTip = tooltipOpts.showAll
157
+ const columnIndex = colRest.index
158
+ const _columnIndex = colRest._index
159
+ const isEdit = isEnableConf(editRender)
160
+ const resizeHeight = resizeHeightFlag ? rowRest.resizeHeight : 0
161
+ let fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
162
+ const isCellPadding = XEUtils.eqNull(padding) ? (allPadding === null ? cellOpts.padding : allPadding) : padding
163
+ const cellOverflow = XEUtils.eqNull(showOverflow) ? allShowOverflow : showOverflow
164
+ const showEllipsis = cellOverflow === 'ellipsis'
165
+ const showTitle = cellOverflow === 'title'
166
+ const showTooltip = cellOverflow === true || cellOverflow === 'tooltip'
167
+ const hasEllipsis = isAllOverflow || showTitle || showTooltip || showEllipsis
168
+ const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
169
+ const isCsHeight = !!customCellHeight
170
+ const isRsHeight = resizeHeight > 0
171
+ let isDirty
172
+ const tdOns: any = {}
173
+ const cellAlign = align || (compConf ? compConf.tableCellAlign : '') || allAlign
174
+ const cellVerticalAlign = XEUtils.eqNull(verticalAlign) ? allVerticalAlign : verticalAlign
175
+ const errorValidItem = validErrorMaps[`${rowid}:${colid}`]
176
+ const showValidTip = editRules && validOpts.showErrorMessage && (validOpts.message === 'default' ? (height || tableData.length > 1) : validOpts.message === 'inline')
177
+ const tdAttrs: any = { colid }
178
+ const cellParams: VxeTableDefines.CellRenderBodyParams & {
179
+ $table: VxeTableConstructor<any> & VxeTablePrivateMethods
180
+ } = {
181
+ $table: $xeTable,
182
+ $grid: $xeGrid,
183
+ $gantt: $xeGantt,
184
+ isEdit: false,
185
+ seq,
186
+ rowid,
187
+ row,
188
+ rowIndex,
189
+ $rowIndex,
190
+ _rowIndex,
191
+ column,
192
+ columnIndex,
193
+ $columnIndex,
194
+ _columnIndex,
195
+ fixed: fixedType,
196
+ source: sourceType,
197
+ type: renderType,
198
+ isHidden: !!fixedHiddenColumn,
199
+ level: rowLevel,
200
+ visibleData: afterFullData,
201
+ data: tableData,
202
+ items
203
+ }
204
+ let isRowDragCell = false
205
+ let isDisabledDrag = false
206
+ if (rowOpts.drag) {
207
+ isRowDragCell = rowDragOpts.trigger === 'row' || (column.dragSort && rowDragOpts.trigger === 'cell')
208
+ }
209
+ if (isRowDragCell) {
210
+ isDisabledDrag = !!(dragDisabledMethod && dragDisabledMethod(cellParams))
211
+ }
212
+ // hover 进入事件
213
+ if (showTitle || showTooltip || showAllTip || tooltipConfig) {
214
+ tdOns.onMouseover = (evnt: MouseEvent) => {
215
+ if (!isVMScrollProcess()) {
216
+ if (showTitle) {
217
+ updateCellTitle(evnt.currentTarget, column)
218
+ } else if (showTooltip || showAllTip) {
219
+ // 如果配置了显示 tooltip
220
+ $xeTable.triggerBodyTooltipEvent(evnt, cellParams)
221
+ }
222
+ }
223
+ $xeTable.dispatchEvent('cell-mouseenter', Object.assign({ cell: evnt.currentTarget }, cellParams), evnt)
224
+ }
225
+ }
226
+ // hover 退出事件
227
+ if (showTooltip || showAllTip || tooltipConfig) {
228
+ tdOns.onMouseleave = (evnt: MouseEvent) => {
229
+ if (!isVMScrollProcess()) {
230
+ if (showTooltip || showAllTip) {
231
+ $xeTable.handleTargetLeaveEvent(evnt)
232
+ }
233
+ }
234
+ $xeTable.dispatchEvent('cell-mouseleave', Object.assign({ cell: evnt.currentTarget }, cellParams), evnt)
235
+ }
236
+ }
237
+ // 按下事件处理
238
+ if (isRowDragCell || checkboxOpts.range || mouseConfig) {
239
+ tdOns.onMousedown = (evnt: MouseEvent) => {
240
+ $xeTable.triggerCellMousedownEvent(evnt, cellParams)
241
+ }
242
+ }
243
+ // 拖拽列事件
244
+ if (isRowDragCell) {
245
+ tdOns.onMouseup = $xeTable.triggerCellMouseupEvent
246
+ }
247
+ // 点击事件处理
248
+ tdOns.onClick = (evnt: MouseEvent) => {
249
+ $xeTable.triggerCellClickEvent(evnt, cellParams)
250
+ }
251
+ // 双击事件处理
252
+ tdOns.onDblclick = (evnt: MouseEvent) => {
253
+ $xeTable.triggerCellDblclickEvent(evnt, cellParams)
254
+ }
255
+ let isMergeCell = false
256
+ let mergeColspan = 1
257
+ let mergeRowspan = 1
258
+ // 合并行或列
259
+ if (mergeBodyFlag && mergeBodyList.length) {
260
+ const spanRest = mergeBodyCellMaps[`${_rowIndex}:${_columnIndex}`]
261
+ if (spanRest) {
262
+ const { rowspan, colspan } = spanRest
263
+ if (!rowspan || !colspan) {
264
+ return renderEmptyElement($xeTable)
265
+ }
266
+ if (rowspan > 1) {
267
+ isMergeCell = true
268
+ mergeRowspan = rowspan
269
+ tdAttrs.rowspan = rowspan
270
+ }
271
+ if (colspan > 1) {
272
+ isMergeCell = true
273
+ mergeColspan = colspan
274
+ tdAttrs.colspan = colspan
275
+ }
276
+ }
277
+ } else if (spanMethod) {
278
+ // 自定义合并行或列的方法
279
+ const { rowspan = 1, colspan = 1 } = spanMethod(cellParams) || {}
280
+ if (!rowspan || !colspan) {
281
+ return renderEmptyElement($xeTable)
282
+ }
283
+ if (rowspan > 1) {
284
+ isMergeCell = true
285
+ mergeRowspan = rowspan
286
+ tdAttrs.rowspan = rowspan
287
+ }
288
+ if (colspan > 1) {
289
+ isMergeCell = true
290
+ mergeColspan = colspan
291
+ tdAttrs.colspan = colspan
292
+ }
293
+ }
294
+ // 如果被合并不可隐藏
295
+ if (fixedHiddenColumn && isMergeCell) {
296
+ if (tdAttrs.colspan > 1 || tdAttrs.rowspan > 1) {
297
+ fixedHiddenColumn = false
298
+ }
299
+ }
300
+ // 如果编辑列开启显示状态
301
+ if (!fixedHiddenColumn && editConfig && (editOpts.showStatus || editOpts.showUpdateStatus) && keepUpdateFieldMaps[field]) {
302
+ isDirty = $xeTable.isUpdateByRow(row, field)
303
+ }
304
+
305
+ const isVNAutoHeight = !hasEllipsis && (scrollYLoad || scrollXLoad)
306
+ let cellHeight = getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight)
307
+
308
+ const isLastColumn = $columnIndex === columns.length - 1
309
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
310
+
311
+ let isVNPreEmptyStatus = false
312
+ if (!isMergeCell) {
313
+ if (!dragRow || getRowid($xeTable, dragRow) !== rowid) {
314
+ if (overflowY && scrollYLoad && tableData.length > 16 && !treeConfig && !virtualYOpts.immediate && (_rowIndex < scrollYStore.visibleStartIndex - scrollYStore.preloadSize || _rowIndex > scrollYStore.visibleEndIndex + scrollYStore.preloadSize)) {
315
+ isVNPreEmptyStatus = true
316
+ } else if (overflowX && scrollXLoad && tableColumn.length > 10 && !virtualXOpts.immediate && !column.fixed && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
317
+ isVNPreEmptyStatus = true
318
+ }
319
+ }
320
+ }
321
+
322
+ if (mergeRowspan > 1) {
323
+ const mEndRow = afterFullData[_rowIndex + mergeRowspan - 1]
324
+ if (mEndRow) {
325
+ const meRowRest = fullAllDataRowIdData[getRowid($xeTable, mEndRow)]
326
+ if (meRowRest) {
327
+ cellHeight += meRowRest.oTop + getCellRestHeight(meRowRest, cellOpts, rowOpts, defaultRowHeight) - rowRest.oTop - getCellRestHeight(rowRest, cellOpts, rowOpts, defaultRowHeight)
328
+ }
329
+ }
330
+ }
331
+
332
+ const tcStyle: Record<string, string> = {}
333
+ if (hasEllipsis && resizeWidthFlag) {
334
+ let mergeColWidth = 0
335
+ if (mergeColspan > 1) {
336
+ for (let index = 1; index < mergeColspan; index++) {
337
+ const nextColumn = visibleColumn[columnIndex + index]
338
+ if (nextColumn) {
339
+ mergeColWidth += nextColumn.renderWidth
340
+ }
341
+ }
342
+ }
343
+ tcStyle.width = `${column.renderWidth + mergeColWidth - cellOffsetWidth}px`
344
+ }
345
+ if (scrollYLoad || scrollXLoad || hasEllipsis || isCsHeight || isRsHeight) {
346
+ tcStyle.height = `${cellHeight}px`
347
+ } else {
348
+ tcStyle.minHeight = `${cellHeight}px`
349
+ }
350
+
351
+ const tdVNs: VxeComponentSlotType[] = []
352
+ if (fixedHiddenColumn && isAllOverflow) {
353
+ tdVNs.push(
354
+ h('div', {
355
+ key: 'tc',
356
+ class: ['vxe-cell', {
357
+ 'c--title': showTitle,
358
+ 'c--tooltip': showTooltip,
359
+ 'c--ellipsis': showEllipsis
360
+ }],
361
+ style: tcStyle
362
+ })
363
+ )
364
+ } else {
365
+ // 渲染单元格
366
+ if (treeConfig) {
367
+ tdVNs.push(...renderLine(rowid, cellParams, cellHeight))
368
+ }
369
+ const clVNs: VxeComponentSlotType[] = []
370
+ if (!isVNPreEmptyStatus) {
371
+ clVNs.push(
372
+ h('div', {
373
+ colid,
374
+ rowid,
375
+ class: 'vxe-cell--wrapper vxe-body-cell--wrapper'
376
+ }, column.renderCell(cellParams))
377
+ )
378
+ }
379
+ tdVNs.push(
380
+ h('div', {
381
+ key: 'tc',
382
+ class: ['vxe-cell', {
383
+ 'c--title': showTitle,
384
+ 'c--tooltip': showTooltip,
385
+ 'c--ellipsis': showEllipsis
386
+ }],
387
+ style: tcStyle,
388
+ title: showTitle ? $xeTable.getCellLabel(row, column) : null
389
+ }, clVNs)
390
+ )
391
+ if (showValidTip && errorValidItem) {
392
+ const errRule = errorValidItem.rule
393
+ const validSlot = slots ? slots.valid : null
394
+ const validParams = { ...cellParams, ...errorValidItem, rule: errorValidItem }
395
+ tdVNs.push(
396
+ h('div', {
397
+ key: 'tcv',
398
+ class: ['vxe-cell--valid-error-tip', getPropClass(validOpts.className, validParams)],
399
+ style: errRule && errRule.maxWidth
400
+ ? {
401
+ width: `${errRule.maxWidth}px`
402
+ }
403
+ : null
404
+ }, [
405
+ h('div', {
406
+ class: `vxe-cell--valid-error-wrapper vxe-cell--valid-error-theme-${validOpts.theme || 'normal'}`
407
+ }, [
408
+ validSlot
409
+ ? $xeTable.callSlot(validSlot, validParams)
410
+ : [
411
+ h('span', {
412
+ class: 'vxe-cell--valid-error-msg'
413
+ }, errorValidItem.content)
414
+ ]
415
+ ])
416
+ ])
417
+ )
418
+ }
419
+ }
420
+
421
+ let showAreaRowStatus = false
422
+ if (mouseConfig && mouseOpts.area && !_columnIndex && selectCellToRow) {
423
+ showAreaRowStatus = true
424
+ }
425
+
426
+ if (!fixedHiddenColumn && showResizable && isAllColumnDrag) {
427
+ tdVNs.push(
428
+ h('div', {
429
+ key: 'tcc',
430
+ class: ['vxe-cell--col-resizable', {
431
+ 'is--line': !border || border === 'none'
432
+ }],
433
+ onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
434
+ onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
435
+ })
436
+ )
437
+ }
438
+
439
+ if ((rowResize || isAllRowDrag) && rowOpts.resizable) {
440
+ tdVNs.push(
441
+ h('div', {
442
+ key: 'tcr',
443
+ class: 'vxe-cell--row-resizable',
444
+ onMousedown: (evnt: MouseEvent) => $xeTable.handleRowResizeMousedownEvent(evnt, cellParams),
445
+ onDblclick: (evnt: MouseEvent) => $xeTable.handleRowResizeDblclickEvent(evnt, cellParams)
446
+ })
447
+ )
448
+ }
449
+
450
+ return h('td', {
451
+ class: [
452
+ 'vxe-table--column vxe-body--column',
453
+ colid,
454
+ cellVerticalAlign ? `col--vertical-${cellVerticalAlign}` : '',
455
+ cellAlign ? `col--${cellAlign}` : '',
456
+ type ? `col--${type}` : '',
457
+ {
458
+ 'col--last': isLastColumn,
459
+ 'col--tree-node': treeNode,
460
+ 'col--edit': isEdit,
461
+ 'col--ellipsis': hasEllipsis,
462
+ 'col--cs-height': isCsHeight,
463
+ 'col--rs-height': isRsHeight,
464
+ 'col--to-row': showAreaRowStatus,
465
+ 'col--auto-height': isVNAutoHeight,
466
+ 'fixed--width': !isAutoCellWidth,
467
+ 'fixed--hidden': fixedHiddenColumn,
468
+ 'is--padding': isCellPadding,
469
+ 'is--progress': (fixedHiddenColumn && isAllOverflow) || isVNPreEmptyStatus,
470
+ 'is--drag-cell': isRowDragCell && (isCrossDrag || isPeerDrag || !rowLevel),
471
+ 'is--drag-disabled': isDisabledDrag,
472
+ 'col--dirty': isDirty,
473
+ 'col--active': editConfig && isEdit && (actived.row === row && (actived.column === column || editOpts.mode === 'row')),
474
+ 'col--valid-error': !!errorValidItem,
475
+ 'show--valid-bg': errorValidItem && validOpts.showErrorBackground,
476
+ 'col--current': currentColumn === column
477
+ },
478
+ getPropClass(compCellClassName, cellParams),
479
+ getPropClass(className, cellParams),
480
+ getPropClass(allCellClassName, cellParams)
481
+ ],
482
+ key: columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || rowOpts.useKey || columnOpts.drag ? colid : $columnIndex,
483
+ ...tdAttrs,
484
+ style: Object.assign({}, XEUtils.isFunction(compCellStyle) ? compCellStyle(cellParams) : compCellStyle, XEUtils.isFunction(cellStyle) ? cellStyle(cellParams) : cellStyle),
485
+ ...tdOns
486
+ }, isOptimizeMode && fixedHiddenColumn ? [] : tdVNs)
487
+ }
488
+
489
+ const renderRows = (fixedType: 'left' | 'right' | '', isOptimizeMode: boolean, tableData: any[], tableColumn: VxeTableDefines.ColumnInfo[]) => {
490
+ const $xeGrid = $xeTable.xeGrid
491
+ const $xeGantt = $xeTable.xeGantt
492
+
493
+ const { stripe, rowKey, highlightHoverRow, rowClassName, rowStyle, editConfig, treeConfig } = tableProps
494
+ const { hasFixedColumn, treeExpandedFlag, scrollYLoad, isAllOverflow, rowExpandedFlag, expandColumn, selectRadioRow, pendingRowFlag, rowExpandHeightFlag, isRowGroupStatus } = tableReactData
495
+ const { fullAllDataRowIdData, fullColumnIdData, treeExpandedMaps, pendingRowMaps, rowExpandedMaps, currentRow } = tableInternalData
496
+ const checkboxOpts = computeCheckboxOpts.value
497
+ const radioOpts = computeRadioOpts.value
498
+ const treeOpts = computeTreeOpts.value
499
+ const editOpts = computeEditOpts.value
500
+ const rowOpts = computeRowOpts.value
501
+ const columnOpts = computeColumnOpts.value
502
+ const { transform, seqMode } = treeOpts
503
+ const childrenField = treeOpts.children || treeOpts.childrenField
504
+ const rows: any[] = []
505
+ const { handleGetRowId } = createHandleGetRowId($xeTable)
506
+ const isDeepRow = treeConfig || isRowGroupStatus
507
+ tableData.forEach((row, $rowIndex) => {
508
+ const rowid = handleGetRowId(row)
509
+ const rowRest = fullAllDataRowIdData[rowid] || {}
510
+ let rowIndex = $rowIndex
511
+ let rowLevel = 0
512
+ let seq: string | number = -1
513
+ let _rowIndex = -1
514
+ const hasRowGroupAggregate = isRowGroupStatus && row.isAggregate
515
+ const trOn: Record<string, any> = {}
516
+ // 当前行事件
517
+ if (rowOpts.isHover || highlightHoverRow) {
518
+ trOn.onMouseover = (evnt: MouseEvent) => {
519
+ if (isVMScrollProcess()) {
520
+ return
521
+ }
522
+ $xeTable.triggerHoverEvent(evnt, { row, rowIndex })
523
+ }
524
+ trOn.onMouseleave = () => {
525
+ if (isVMScrollProcess()) {
526
+ return
527
+ }
528
+ $xeTable.clearHoverRow()
529
+ }
530
+ }
531
+ if (rowRest) {
532
+ rowIndex = rowRest.index
533
+ _rowIndex = rowRest._index
534
+ rowLevel = rowRest.level
535
+ seq = rowRest.seq
536
+ if (hasRowGroupAggregate || (treeConfig && transform && seqMode === 'increasing')) {
537
+ seq = rowRest._index + 1
538
+ } else if ((treeConfig && seqMode === 'fixed')) {
539
+ seq = rowRest._tIndex + 1
540
+ }
541
+ }
542
+ const params = {
543
+ $table: $xeTable,
544
+ seq,
545
+ rowid,
546
+ fixed: fixedType,
547
+ type: renderType,
548
+ level: rowLevel,
549
+ row,
550
+ rowIndex,
551
+ $rowIndex,
552
+ _rowIndex
553
+ }
554
+ // 行是否被展开
555
+ const isExpandRow = expandColumn && !!rowExpandedFlag && !!rowExpandedMaps[rowid]
556
+ // 树节点是否被展开
557
+ let isExpandTree = false
558
+ let rowChildren = []
559
+ let isNewRow = false
560
+ if (editConfig) {
561
+ isNewRow = $xeTable.isInsertByRow(row)
562
+ }
563
+ if (treeConfig && !scrollYLoad && !transform) {
564
+ rowChildren = row[childrenField]
565
+ isExpandTree = !!treeExpandedFlag && rowChildren && rowChildren.length > 0 && !!treeExpandedMaps[rowid]
566
+ }
567
+ // 拖拽行事件
568
+ if (rowOpts.drag && !isRowGroupStatus && (!treeConfig || transform)) {
569
+ trOn.onDragstart = $xeTable.handleRowDragDragstartEvent
570
+ trOn.onDragend = $xeTable.handleRowDragDragendEvent
571
+ trOn.onDragover = $xeTable.handleRowDragDragoverEvent
572
+ }
573
+ const trClass = [
574
+ 'vxe-body--row',
575
+ isDeepRow ? `row--level-${rowLevel}` : '',
576
+ {
577
+ 'row--stripe': stripe && (_rowIndex + 1) % 2 === 0,
578
+ 'is--new': isNewRow,
579
+ 'is--expand-row': isExpandRow,
580
+ 'is--expand-tree': isExpandTree,
581
+ 'row--new': isNewRow && (editOpts.showStatus || editOpts.showInsertStatus),
582
+ 'row--radio': radioOpts.highlight && $xeTable.eqRow(selectRadioRow, row),
583
+ 'row--checked': checkboxOpts.highlight && $xeTable.isCheckedByCheckboxRow(row),
584
+ 'row--pending': !!pendingRowFlag && !!pendingRowMaps[rowid],
585
+ 'row--group': hasRowGroupAggregate,
586
+ 'row--current': currentRow && rowid === getRowid($xeTable, currentRow)
587
+ },
588
+ getPropClass(rowClassName, params)
589
+ ]
590
+ const tdVNs = tableColumn.map((column, $columnIndex) => {
591
+ return renderTdColumn(seq, rowid, fixedType, isOptimizeMode, rowLevel, row, rowIndex, $rowIndex, _rowIndex, column, $columnIndex, tableColumn, tableData)
592
+ })
593
+ rows.push(
594
+ h('tr', {
595
+ class: trClass,
596
+ rowid: rowid,
597
+ style: rowStyle ? (XEUtils.isFunction(rowStyle) ? rowStyle(params) : rowStyle) : null,
598
+ key: rowKey || rowOpts.useKey || rowOpts.drag || columnOpts.drag || isRowGroupStatus || treeConfig ? rowid : $rowIndex,
599
+ ...trOn
600
+ }, tdVNs)
601
+ )
602
+ // 如果行被展开了
603
+ if (isExpandRow) {
604
+ const expandOpts = computeExpandOpts.value
605
+ const { height: expandHeight, padding, mode: expandMode } = expandOpts
606
+ if (expandMode === 'fixed') {
607
+ const currExpHeight = rowRest.expandHeight
608
+ let expHeight = 0
609
+ if (rowExpandHeightFlag) {
610
+ if (currExpHeight || expandHeight) {
611
+ expHeight = (currExpHeight || expandHeight || 0) + 1
612
+ }
613
+ }
614
+ rows.push(
615
+ h('tr', {
616
+ class: 'vxe-body--row-expanded-place',
617
+ key: `expand_${rowid}`,
618
+ rowid
619
+ }, [
620
+ h('td', {
621
+ class: 'vxe-body--row-expanded-place-column',
622
+ colspan: tableColumn.length,
623
+ style: {
624
+ height: `${expHeight}px`
625
+ }
626
+ })
627
+ ])
628
+ )
629
+ } else {
630
+ const cellStyle: any = {}
631
+ if (expandHeight) {
632
+ cellStyle.height = `${expandHeight}px`
633
+ }
634
+ if (treeConfig) {
635
+ cellStyle.paddingLeft = `${(rowLevel * treeOpts.indent) + 30}px`
636
+ }
637
+ const { showOverflow } = expandColumn || {}
638
+ const colid = expandColumn.id
639
+ const colRest = fullColumnIdData[colid] || {}
640
+ const hasEllipsis = XEUtils.eqNull(showOverflow) ? isAllOverflow : showOverflow
641
+ let columnIndex = -1
642
+ let $columnIndex = -1
643
+ let _columnIndex = -1
644
+ if (colRest) {
645
+ columnIndex = colRest.index
646
+ $columnIndex = colRest.$index
647
+ _columnIndex = colRest._index
648
+ }
649
+ const expandParams: VxeTableDefines.CellRenderDataParams = {
650
+ $table: $xeTable,
651
+ $grid: $xeGrid,
652
+ $gantt: $xeGantt,
653
+ seq,
654
+ column: expandColumn as VxeTableDefines.ColumnInfo,
655
+ columnIndex,
656
+ $columnIndex,
657
+ _columnIndex,
658
+ fixed: fixedType,
659
+ source: sourceType,
660
+ type: renderType,
661
+ level: rowLevel,
662
+ row,
663
+ rowid,
664
+ rowIndex,
665
+ $rowIndex,
666
+ _rowIndex,
667
+ isHidden: false,
668
+ isEdit: false,
669
+ visibleData: [],
670
+ data: [],
671
+ items: []
672
+ }
673
+ rows.push(
674
+ h('tr', {
675
+ class: ['vxe-body--expanded-row', {
676
+ 'is--padding': padding
677
+ }],
678
+ key: `expand_${rowid}`
679
+ }, [
680
+ h('td', {
681
+ class: ['vxe-body--expanded-column', {
682
+ 'fixed--hidden': fixedType && !hasFixedColumn,
683
+ 'col--ellipsis': hasEllipsis
684
+ }],
685
+ colspan: tableColumn.length
686
+ }, [
687
+ h('div', {
688
+ class: ['vxe-body--expanded-cell', {
689
+ 'is--ellipsis': expandHeight
690
+ }],
691
+ style: cellStyle
692
+ }, [
693
+ expandColumn.renderData(expandParams)
694
+ ])
695
+ ])
696
+ ])
697
+ )
698
+ }
699
+ }
700
+ // 如果是树形表格
701
+ if (isExpandTree) {
702
+ rows.push(...renderRows(fixedType, isOptimizeMode, rowChildren, tableColumn))
703
+ }
704
+ })
705
+ return rows
706
+ }
707
+
708
+ onMounted(() => {
709
+ nextTick(() => {
710
+ const { fixedType } = props
711
+ const { elemStore } = tableInternalData
712
+ const prefix = `${fixedType || 'main'}-body-`
713
+ elemStore[`${prefix}wrapper`] = refElem
714
+ elemStore[`${prefix}scroll`] = refBodyScroll
715
+ elemStore[`${prefix}table`] = refBodyTable
716
+ elemStore[`${prefix}colgroup`] = refBodyColgroup
717
+ elemStore[`${prefix}list`] = refBodyTBody
718
+ elemStore[`${prefix}xSpace`] = refBodyXSpace
719
+ elemStore[`${prefix}ySpace`] = refBodyYSpace
720
+ elemStore[`${prefix}emptyBlock`] = refBodyEmptyBlock
721
+ })
722
+ })
723
+
724
+ onUnmounted(() => {
725
+ const { fixedType } = props
726
+ const { elemStore } = tableInternalData
727
+ const prefix = `${fixedType || 'main'}-body-`
728
+ elemStore[`${prefix}wrapper`] = null
729
+ elemStore[`${prefix}scroll`] = null
730
+ elemStore[`${prefix}table`] = null
731
+ elemStore[`${prefix}colgroup`] = null
732
+ elemStore[`${prefix}list`] = null
733
+ elemStore[`${prefix}xSpace`] = null
734
+ elemStore[`${prefix}ySpace`] = null
735
+ elemStore[`${prefix}emptyBlock`] = null
736
+ })
737
+
738
+ const renderVN = () => {
739
+ const { slots } = tableContext
740
+ const $xeGrid = $xeTable.xeGrid
741
+ const $xeGantt = $xeTable.xeGantt
742
+
743
+ const { fixedColumn, fixedType, tableColumn } = props
744
+ const { mouseConfig } = tableProps
745
+ const { isGroup, tableData, isColLoading, overflowX, scrollXLoad, scrollYLoad, dragRow, dragCol } = tableReactData
746
+ const { visibleColumn, fullAllDataRowIdData, fullColumnIdData } = tableInternalData
747
+ const emptyOpts = computeEmptyOpts.value
748
+ const mouseOpts = computeMouseOpts.value
749
+ const isBodyRenderOptimize = computeIsBodyRenderOptimize.value
750
+
751
+ let renderDataList = tableData
752
+ let renderColumnList = tableColumn as VxeTableDefines.ColumnInfo[]
753
+ const isOptimizeMode = isBodyRenderOptimize
754
+
755
+ if (!isColLoading && (fixedType || !overflowX)) {
756
+ renderColumnList = visibleColumn
757
+ }
758
+
759
+ if (fixedType) {
760
+ if (isOptimizeMode) {
761
+ renderColumnList = fixedColumn || []
762
+ }
763
+ }
764
+
765
+ // 行拖拽
766
+ if (scrollYLoad && dragRow) {
767
+ if (renderDataList.length > 2) {
768
+ const dRowRest = fullAllDataRowIdData[getRowid($xeTable, dragRow)]
769
+ if (dRowRest) {
770
+ const drIndex = dRowRest._index
771
+ const firstRow = renderDataList[0]
772
+ const lastRow = renderDataList[renderDataList.length - 1]
773
+ const firstRowRest = fullAllDataRowIdData[getRowid($xeTable, firstRow)]
774
+ const lastRowRest = fullAllDataRowIdData[getRowid($xeTable, lastRow)]
775
+ if (firstRowRest && lastRowRest) {
776
+ const frIndex = firstRowRest._index
777
+ const lrIndex = lastRowRest._index
778
+ if (drIndex < frIndex) {
779
+ renderDataList = [dragRow].concat(renderDataList)
780
+ } else if (drIndex > lrIndex) {
781
+ renderDataList = renderDataList.concat([dragRow])
782
+ }
783
+ }
784
+ }
785
+ }
786
+ }
787
+
788
+ if (!fixedType && !isGroup) {
789
+ // 列拖拽
790
+ if (scrollXLoad && dragCol) {
791
+ if (renderColumnList.length > 2) {
792
+ const dCowRest = fullColumnIdData[dragCol.id]
793
+ if (dCowRest) {
794
+ const dcIndex = dCowRest._index
795
+ const firstCol = renderColumnList[0]
796
+ const lastCol = renderColumnList[renderColumnList.length - 1]
797
+ const firstColRest = fullColumnIdData[firstCol.id]
798
+ const lastColRest = fullColumnIdData[lastCol.id]
799
+ if (firstColRest && lastColRest) {
800
+ const fcIndex = firstColRest._index
801
+ const lcIndex = lastColRest._index
802
+ if (dcIndex < fcIndex) {
803
+ renderColumnList = [dragCol].concat(renderColumnList)
804
+ } else if (dcIndex > lcIndex) {
805
+ renderColumnList = renderColumnList.concat([dragCol])
806
+ }
807
+ }
808
+ }
809
+ }
810
+ }
811
+ }
812
+
813
+ let emptyContent: string | VxeComponentSlotType | VxeComponentSlotType[]
814
+ const emptySlot = slots ? slots.empty : null
815
+ const emptyParams = { $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt }
816
+ if (emptySlot) {
817
+ emptyContent = $xeTable.callSlot(emptySlot, emptyParams)
818
+ } else {
819
+ const compConf = emptyOpts.name ? renderer.get(emptyOpts.name) : null
820
+ const rtEmptyView = compConf ? (compConf.renderTableEmpty || compConf.renderTableEmptyView || compConf.renderEmpty) : null
821
+ if (rtEmptyView) {
822
+ emptyContent = getSlotVNs(rtEmptyView(emptyOpts, emptyParams))
823
+ } else {
824
+ emptyContent = tableProps.emptyText || getI18n('vxe.table.emptyText')
825
+ }
826
+ }
827
+
828
+ return h('div', {
829
+ ref: refElem,
830
+ class: ['vxe-table--body-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
831
+ xid: xID
832
+ }, [
833
+ h('div', {
834
+ ref: refBodyScroll,
835
+ class: 'vxe-table--body-inner-wrapper',
836
+ onScroll (evnt) {
837
+ $xeTable.triggerBodyScrollEvent(evnt, fixedType)
838
+ }
839
+ }, [
840
+ fixedType
841
+ ? renderEmptyElement($xeTable)
842
+ : h('div', {
843
+ ref: refBodyXSpace,
844
+ class: 'vxe-body--x-space'
845
+ }),
846
+ h('div', {
847
+ ref: refBodyYSpace,
848
+ class: 'vxe-body--y-space'
849
+ }),
850
+ h('table', {
851
+ ref: refBodyTable,
852
+ class: 'vxe-table--body',
853
+ xid: xID,
854
+ cellspacing: 0,
855
+ cellpadding: 0,
856
+ border: 0,
857
+ xvm: isOptimizeMode ? '1' : null
858
+ }, [
859
+ /**
860
+ * 列宽
861
+ */
862
+ h('colgroup', {
863
+ ref: refBodyColgroup
864
+ }, renderColumnList.map((column, $columnIndex) => {
865
+ return h('col', {
866
+ name: column.id,
867
+ key: $columnIndex,
868
+ style: {
869
+ width: `${column.renderWidth}px`
870
+ }
871
+ })
872
+ })),
873
+ /**
874
+ * 内容
875
+ */
876
+ h('tbody', {
877
+ ref: refBodyTBody
878
+ }, renderRows(fixedType, isOptimizeMode, renderDataList, renderColumnList))
879
+ ]),
880
+ h('div', {
881
+ class: 'vxe-table--checkbox-range'
882
+ }),
883
+ mouseConfig && mouseOpts.area
884
+ ? h('div', {
885
+ class: 'vxe-table--cell-area',
886
+ xid: xID
887
+ }, [
888
+ h('span', {
889
+ class: 'vxe-table--cell-main-area'
890
+ }, mouseOpts.extension
891
+ ? [
892
+ h('span', {
893
+ class: 'vxe-table--cell-main-area-btn',
894
+ onMousedown (evnt: MouseEvent) {
895
+ if ($xeTable.triggerCellAreaExtendMousedownEvent) {
896
+ $xeTable.triggerCellAreaExtendMousedownEvent(evnt, { $table: $xeTable, fixed: fixedType, type: renderType })
897
+ }
898
+ }
899
+ })
900
+ ]
901
+ : []),
902
+ h('span', {
903
+ class: 'vxe-table--cell-clip-area'
904
+ }),
905
+ h('span', {
906
+ class: 'vxe-table--cell-extend-area'
907
+ }),
908
+ h('span', {
909
+ class: 'vxe-table--cell-multi-area'
910
+ }),
911
+ h('span', {
912
+ class: 'vxe-table--cell-active-area'
913
+ }),
914
+ h('span', {
915
+ class: 'vxe-table--cell-row-status-area'
916
+ })
917
+ ])
918
+ : renderEmptyElement($xeTable),
919
+ !fixedType
920
+ ? h('div', {
921
+ class: 'vxe-table--empty-block',
922
+ ref: refBodyEmptyBlock
923
+ }, [
924
+ h('div', {
925
+ class: 'vxe-table--empty-content'
926
+ }, emptyContent)
927
+ ])
928
+ : renderEmptyElement($xeTable)
929
+ ])
930
+ ])
931
+ }
932
+
933
+ return renderVN
934
+ }
935
+ })