vxe-table 4.23.8 → 4.23.9

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