vxe-table 4.23.7 → 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 (148) hide show
  1. package/dist/all.esm.js +5859 -4018
  2. package/es/colgroup/index.js +1 -1
  3. package/es/column/index.js +1 -1
  4. package/es/components.d.ts +3 -0
  5. package/es/components.js +4 -8
  6. package/es/grid/index.js +1 -1
  7. package/es/grid/src/emits.js +1 -15
  8. package/es/grid/src/grid.js +398 -121
  9. package/es/grid/src/props.js +1 -1
  10. package/es/index.esm.js +6 -0
  11. package/es/index.js +6 -0
  12. package/es/table/index.js +1 -1
  13. package/es/table/module/custom/hook.js +50 -43
  14. package/es/table/module/custom/panel.js +778 -528
  15. package/es/table/module/edit/hook.js +141 -63
  16. package/es/table/module/export/export-panel.js +400 -317
  17. package/es/table/module/export/hook.js +396 -338
  18. package/es/table/module/export/import-panel.js +153 -124
  19. package/es/table/module/filter/hook.js +17 -3
  20. package/es/table/module/filter/panel.js +147 -85
  21. package/es/table/module/keyboard/hook.js +9 -5
  22. package/es/table/module/menu/hook.js +1 -1
  23. package/es/table/module/menu/panel.js +198 -127
  24. package/es/table/module/validator/hook.js +1 -1
  25. package/es/table/render/index.js +152 -99
  26. package/es/table/src/body.js +356 -234
  27. package/es/table/src/cell.js +427 -270
  28. package/es/table/src/columnInfo.js +2 -1
  29. package/es/table/src/footer.js +145 -100
  30. package/es/table/src/group.js +7 -3
  31. package/es/table/src/header.js +230 -173
  32. package/es/table/src/props.js +1 -1
  33. package/es/table/src/table.js +1504 -1031
  34. package/es/table/src/util.js +15 -19
  35. package/es/toolbar/index.js +1 -1
  36. package/es/toolbar/src/toolbar.js +133 -76
  37. package/es/ui/index.d.ts +0 -1
  38. package/es/ui/index.js +1 -2
  39. package/es/ui/src/dom.js +9 -6
  40. package/es/ui/src/log.js +1 -1
  41. package/es/ui/src/utils.d.ts +1 -1
  42. package/es/v-x-e-table/index.d.ts +0 -1
  43. package/es/v-x-e-table/index.js +0 -1
  44. package/lib/colgroup/index.js +5 -5
  45. package/lib/column/index.js +5 -5
  46. package/lib/components.js +8 -12
  47. package/lib/grid/index.js +4 -4
  48. package/lib/grid/src/emits.js +1 -15
  49. package/lib/grid/src/grid.js +419 -142
  50. package/lib/grid/src/props.js +2 -2
  51. package/lib/index.common.js +6 -0
  52. package/lib/index.js +6 -0
  53. package/lib/index.umd.js +5825 -3945
  54. package/lib/index.umd.min.js +3 -3
  55. package/lib/table/index.js +5 -5
  56. package/lib/table/module/custom/hook.js +51 -44
  57. package/lib/table/module/custom/panel.js +790 -540
  58. package/lib/table/module/edit/hook.js +142 -64
  59. package/lib/table/module/export/export-panel.js +406 -323
  60. package/lib/table/module/export/hook.js +419 -361
  61. package/lib/table/module/export/import-panel.js +157 -128
  62. package/lib/table/module/filter/hook.js +18 -4
  63. package/lib/table/module/filter/panel.js +149 -87
  64. package/lib/table/module/keyboard/hook.js +10 -6
  65. package/lib/table/module/menu/hook.js +2 -2
  66. package/lib/table/module/menu/panel.js +199 -128
  67. package/lib/table/module/validator/hook.js +2 -2
  68. package/lib/table/render/index.js +153 -100
  69. package/lib/table/src/body.js +357 -235
  70. package/lib/table/src/cell.js +428 -271
  71. package/lib/table/src/columnInfo.js +3 -2
  72. package/lib/table/src/footer.js +146 -101
  73. package/lib/table/src/group.js +7 -3
  74. package/lib/table/src/header.js +231 -174
  75. package/lib/table/src/props.js +2 -2
  76. package/lib/table/src/table.js +1487 -1045
  77. package/lib/table/src/util.js +15 -19
  78. package/lib/toolbar/index.js +4 -4
  79. package/lib/toolbar/src/toolbar.js +135 -78
  80. package/lib/ui/index.js +1 -3
  81. package/lib/ui/src/dom.js +9 -6
  82. package/lib/ui/src/log.js +1 -1
  83. package/lib/v-x-e-table/index.js +0 -2
  84. package/package.json +8 -3
  85. package/packages/colgroup/index.ts +22 -22
  86. package/packages/column/index.ts +22 -22
  87. package/packages/components.ts +41 -43
  88. package/packages/grid/index.ts +18 -18
  89. package/packages/grid/src/emits.ts +5 -19
  90. package/packages/grid/src/grid.ts +2229 -1925
  91. package/packages/grid/src/props.ts +22 -23
  92. package/packages/index.ts +11 -4
  93. package/packages/locale/lang/fr-FR.ts +15 -15
  94. package/packages/locale/lang/it-IT.ts +4 -4
  95. package/packages/locale/lang/uk-UA.ts +1 -1
  96. package/packages/locale/lang/uz-UZ.ts +13 -13
  97. package/packages/locale/lang/zh-CN.ts +907 -907
  98. package/packages/table/index.ts +26 -26
  99. package/packages/table/module/custom/hook.ts +510 -503
  100. package/packages/table/module/custom/panel.ts +2002 -1743
  101. package/packages/table/module/edit/hook.ts +1224 -1131
  102. package/packages/table/module/export/export-panel.ts +697 -611
  103. package/packages/table/module/export/hook.ts +2160 -2059
  104. package/packages/table/module/export/import-panel.ts +319 -279
  105. package/packages/table/module/export/util.ts +25 -24
  106. package/packages/table/module/filter/hook.ts +519 -501
  107. package/packages/table/module/filter/panel.ts +368 -304
  108. package/packages/table/module/keyboard/hook.ts +498 -494
  109. package/packages/table/module/menu/hook.ts +330 -330
  110. package/packages/table/module/menu/panel.ts +272 -201
  111. package/packages/table/module/validator/hook.ts +653 -635
  112. package/packages/table/render/index.ts +1819 -1744
  113. package/packages/table/src/body.ts +1078 -955
  114. package/packages/table/src/cell.ts +1524 -1359
  115. package/packages/table/src/column.ts +192 -192
  116. package/packages/table/src/columnInfo.ts +232 -232
  117. package/packages/table/src/emits.ts +134 -134
  118. package/packages/table/src/footer.ts +425 -380
  119. package/packages/table/src/group.ts +67 -63
  120. package/packages/table/src/header.ts +642 -581
  121. package/packages/table/src/props.ts +336 -336
  122. package/packages/table/src/store.ts +14 -14
  123. package/packages/table/src/table.ts +16011 -15454
  124. package/packages/table/src/use/cell-view.ts +41 -44
  125. package/packages/table/src/use/index.ts +1 -1
  126. package/packages/table/src/util.ts +1206 -1216
  127. package/packages/toolbar/index.ts +18 -18
  128. package/packages/toolbar/src/toolbar.ts +768 -706
  129. package/packages/ui/index.ts +519 -521
  130. package/packages/ui/src/anime.ts +51 -52
  131. package/packages/ui/src/comp.ts +3 -3
  132. package/packages/ui/src/dom.ts +466 -463
  133. package/packages/ui/src/log.ts +19 -19
  134. package/packages/ui/src/utils.ts +66 -66
  135. package/packages/ui/src/vn.ts +55 -55
  136. package/packages/v-x-e-table/index.d.ts +3 -4
  137. package/packages/v-x-e-table/index.ts +3 -4
  138. package/types/all.d.ts +76 -76
  139. package/types/index.d.ts +4 -4
  140. /package/dist/{iconfont.1792979665397.ttf → iconfont.1793009263429.ttf} +0 -0
  141. /package/dist/{iconfont.1792979665397.woff → iconfont.1793009263429.woff} +0 -0
  142. /package/dist/{iconfont.1792979665397.woff2 → iconfont.1793009263429.woff2} +0 -0
  143. /package/es/{iconfont.1792979665397.ttf → iconfont.1793009263429.ttf} +0 -0
  144. /package/es/{iconfont.1792979665397.woff → iconfont.1793009263429.woff} +0 -0
  145. /package/es/{iconfont.1792979665397.woff2 → iconfont.1793009263429.woff2} +0 -0
  146. /package/lib/{iconfont.1792979665397.ttf → iconfont.1793009263429.ttf} +0 -0
  147. /package/lib/{iconfont.1792979665397.woff → iconfont.1793009263429.woff} +0 -0
  148. /package/lib/{iconfont.1792979665397.woff2 → iconfont.1793009263429.woff2} +0 -0
@@ -1,581 +1,642 @@
1
- import { h, ref, Ref, PropType, inject, nextTick, watch, onMounted, onUnmounted } from 'vue'
2
- import { defineVxeComponent } from '../../ui/src/comp'
3
- import XEUtils from 'xe-utils'
4
- import { VxeUI } from '../../ui'
5
- import { getDefaultConfig, hasEnableConf, isEnableConf } from '../../ui/src/utils'
6
- import { getCalcHeight, convertHeaderColumnToRows, convertHeaderToGridRows } from './util'
7
- import { getSlotVNs } from '../../ui/src/vn'
8
-
9
- import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines, VxeGlobalRendererHandles } from '../../../types'
10
-
11
- const { renderer, renderEmptyElement } = VxeUI
12
-
13
- const sourceType = 'table'
14
- const renderType = 'header'
15
-
16
- export default defineVxeComponent({
17
- name: 'VxeTableHeader',
18
- props: {
19
- tableData: Array as PropType<any[]>,
20
- tableColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
21
- tableGroupColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
22
- fixedColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
23
- fixedType: {
24
- type: String as PropType<'right' | 'left' | ''>,
25
- default: null
26
- }
27
- },
28
- setup (props) {
29
- const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)
30
-
31
- const { xID, props: tableProps, reactData: tableReactData, internalData: tableInternalData } = $xeTable
32
- const { computeColumnOpts, computeColumnDragOpts, computeCellOpts, computeMouseOpts, computeHeaderCellOpts, computeDefaultRowHeight, computeVirtualXOpts, computeFloatingFilterOpts, computeIsHeaderRenderOptimize, computeHeaderTooltipOpts, computeRendererOpts } = $xeTable.getComputeMaps()
33
-
34
- const headerColumn = ref<VxeTableDefines.ColumnInfo[][]>([])
35
-
36
- const refElem = ref() as Ref<HTMLDivElement>
37
- const refHeaderScroll = ref() as Ref<HTMLDivElement>
38
- const refHeaderTable = ref() as Ref<HTMLTableElement>
39
- const refHeaderColgroup = ref() as Ref<HTMLTableColElement>
40
- const refHeaderTHead = ref() as Ref<HTMLTableSectionElement>
41
- const refHeaderXSpace = ref() as Ref<HTMLDivElement>
42
- const refHeaderBorderRepair = ref() as Ref<HTMLDivElement>
43
-
44
- const uploadColumn = () => {
45
- const { showCustomHeader } = tableProps
46
- const { collectColumn, visibleColumn } = tableInternalData
47
- const { tableGroupColumn } = props
48
- const { isGroup } = tableReactData
49
- let spanColumns: VxeTableDefines.ColumnInfo[][] = isGroup ? convertHeaderColumnToRows(tableGroupColumn) : []
50
- let visibleColgroups: VxeTableDefines.ColumnInfo[][] = []
51
- if (showCustomHeader && spanColumns.length > 1) {
52
- visibleColgroups = convertHeaderToGridRows(spanColumns)
53
- spanColumns = visibleColgroups
54
- }
55
- headerColumn.value = spanColumns
56
- nextTick(() => {
57
- $xeTable.dispatchEvent('columns-change', { visibleColgroups, collectColumn, visibleColumn }, null)
58
- })
59
- }
60
-
61
- const renderRows = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], _rowIndex: number, cols: VxeTableDefines.ColumnInfo[]) => {
62
- const $xeGrid = $xeTable.xeGrid
63
- const $xeGantt = $xeTable.xeGantt
64
-
65
- const { fixedType } = props
66
- const { resizable: allResizable, columnKey, showCustomHeader, headerCellClassName, headerCellStyle, showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign, mouseConfig } = tableProps
67
- const { dragCol, scrollXLoad, scrollYLoad, overflowX, mergeHeadFlag, tableColumn, currColFlag } = tableReactData
68
- const { fullColumnIdData, scrollXStore, mergeHeaderList, mergeHeaderCellMaps, currentCol } = tableInternalData
69
- const virtualXOpts = computeVirtualXOpts.value
70
- const columnOpts = computeColumnOpts.value
71
- const columnDragOpts = computeColumnDragOpts.value
72
- const headerTooltipOpts = computeHeaderTooltipOpts.value
73
- const cellOpts = computeCellOpts.value
74
- const defaultRowHeight = computeDefaultRowHeight.value
75
- const headerCellOpts = computeHeaderCellOpts.value
76
- const rendererOpts = computeRendererOpts.value
77
- const mouseOpts = computeMouseOpts.value
78
- const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
79
- const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = columnDragOpts
80
- const isLastRow = _rowIndex === headerGroups.length - 1
81
-
82
- return cols.map((column, $columnIndex) => {
83
- const { type, showHeaderOverflow, headerAlign, align, filters, headerClassName, editRender, cellRender } = column
84
- const colid = column.id
85
- const colRest = fullColumnIdData[colid] || {}
86
- const renderOpts = editRender || cellRender
87
- const compConf = renderOpts && renderOpts.name ? (rendererOpts[renderOpts.name] || renderer.get(renderOpts.name)) : null
88
- const isColGroup = column.children && column.children.length
89
- const fixedHiddenColumn = overflowX && !isColGroup && (fixedType ? column.fixed !== fixedType : !!column.fixed)
90
-
91
- const cellPadding = getDefaultConfig(headerCellOpts.padding, cellOpts.padding)
92
- const isAllCellPadding = cellPadding === true
93
- const isCellPaddingTop = cellPadding ? (isAllCellPadding || cellPadding.top !== false) : false
94
- const isCellPaddingBottom = cellPadding ? (isAllCellPadding || cellPadding.bottom !== false) : false
95
- const isCellPaddingLeft = cellPadding ? (isAllCellPadding || cellPadding.left !== false) : false
96
- const isCellPaddingRight = cellPadding ? (isAllCellPadding || cellPadding.right !== false) : false
97
-
98
- const headOverflow = getDefaultConfig(showHeaderOverflow, allColumnHeaderOverflow)
99
- const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
100
- const showEllipsis = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'ellipsis'
101
- const showTitle = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'title'
102
- const showTooltip = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'tooltip'
103
- const hasEllipsis = showTitle || showTooltip || showEllipsis
104
- let hasFilter = false
105
- let firstFilterOption: VxeTableDefines.FilterOption | null = null
106
- if (filters) {
107
- firstFilterOption = filters[0] as VxeTableDefines.FilterOption
108
- hasFilter = filters.some((item) => item.checked)
109
- }
110
- const columnIndex = colRest.index
111
- const _columnIndex = colRest._index
112
- const cellParams: VxeTableDefines.CellRenderHeaderParams & {
113
- $table: VxeTableConstructor & VxeTablePrivateMethods
114
- } = {
115
- $table: $xeTable,
116
- $grid: $xeGrid,
117
- $gantt: $xeGantt,
118
- rowIndex: _rowIndex,
119
- _rowIndex,
120
- $rowIndex: _rowIndex,
121
- column,
122
- columnIndex,
123
- $columnIndex,
124
- _columnIndex,
125
- firstFilterOption: firstFilterOption as VxeTableDefines.FilterOption,
126
- fixed: fixedType,
127
- source: sourceType,
128
- type: renderType,
129
- isHidden: fixedHiddenColumn,
130
- hasFilter
131
- }
132
- const thAttrs: Record<string, string | number | null> = {
133
- colid
134
- }
135
- let isMergeCell = false
136
- // 合并行或列
137
- if (!showCustomHeader) {
138
- thAttrs.colspan = column.colSpan > 1 ? column.colSpan : null
139
- thAttrs.rowspan = column.rowSpan > 1 ? column.rowSpan : null
140
- }
141
- if (mergeHeadFlag && mergeHeaderList.length && (showCustomHeader || isLastRow)) {
142
- const spanRest = mergeHeaderCellMaps[`${_rowIndex}:${showCustomHeader ? $columnIndex : _columnIndex}`]
143
- if (spanRest) {
144
- const { rowspan, colspan } = spanRest
145
- if (!rowspan || !colspan) {
146
- return null
147
- }
148
- if (rowspan > 1) {
149
- isMergeCell = true
150
- thAttrs.rowspan = rowspan
151
- }
152
- if (colspan > 1) {
153
- isMergeCell = true
154
- thAttrs.colspan = colspan
155
- }
156
- }
157
- }
158
-
159
- const thOns: any = {
160
- onClick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellClickEvent(evnt, cellParams),
161
- onDblclick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellDblclickEvent(evnt, cellParams)
162
- }
163
- const isColDragCell = columnOpts.drag && columnDragOpts.trigger === 'cell'
164
- let isDisabledDrag = false
165
- if (isColDragCell) {
166
- isDisabledDrag = !!(dragDisabledMethod && dragDisabledMethod(cellParams))
167
- }
168
- // 按下事件处理
169
- if (hasEnableConf(mouseConfig, mouseOpts) || isColDragCell) {
170
- thOns.onMousedown = (evnt: MouseEvent) => $xeTable.triggerHeaderCellMousedownEvent(evnt, cellParams)
171
- }
172
- // 拖拽列事件
173
- if (columnOpts.drag) {
174
- thOns.onDragstart = $xeTable.handleHeaderCellDragDragstartEvent
175
- thOns.onDragend = $xeTable.handleHeaderCellDragDragendEvent
176
- thOns.onDragover = $xeTable.handleHeaderCellDragDragoverEvent
177
- if (isColDragCell) {
178
- thOns.onMouseup = $xeTable.handleHeaderCellDragMouseupEvent
179
- }
180
- }
181
- const isLastColumn = $columnIndex === cols.length - 1
182
- const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
183
- const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
184
-
185
- let isVNPreEmptyStatus = false
186
- if (isOptimizeMode && overflowX && !isGroup && !isMergeCell) {
187
- if (!dragCol || dragCol.id !== colid) {
188
- if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
189
- isVNPreEmptyStatus = true
190
- }
191
- }
192
- }
193
-
194
- const tcStyle: Record<string, string> = {}
195
- if (hasEllipsis) {
196
- tcStyle.height = `${currCellHeight}px`
197
- } else {
198
- tcStyle.minHeight = `${currCellHeight}px`
199
- }
200
-
201
- if (showCustomHeader) {
202
- // custom
203
- } else if (isColGroup && !isLastRow) {
204
- let childWidth = 0
205
- XEUtils.eachTree(column.children, (childRow) => {
206
- if (childRow.visible && (!childRow.children || !childRow.children.length)) {
207
- childWidth += childRow.renderWidth
208
- }
209
- })
210
- tcStyle.width = `${childWidth}px`
211
- }
212
-
213
- return h('th', {
214
- class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
215
- [`col--${headAlign}`]: headAlign,
216
- [`col--${type}`]: type,
217
- 'col--last': isLastColumn,
218
- 'col--fixed': column.fixed,
219
- 'col--group': isColGroup,
220
- 'col--ellipsis': hasEllipsis,
221
- 'fixed--width': !isAutoCellWidth,
222
- 'is--pg-top': isCellPaddingTop,
223
- 'is--pg-bottom': isCellPaddingBottom,
224
- 'is--pg-left': isCellPaddingLeft,
225
- 'is--pg-right': isCellPaddingRight,
226
- 'is--sortable': column.sortable,
227
- 'col--filter': !!filters,
228
- 'is--filter-active': hasFilter,
229
- 'is--drag-active': columnOpts.drag && !column.fixed && !isDisabledDrag && (isCrossDrag || isPeerDrag || !column.parentId),
230
- 'is--drag-disabled': columnOpts.drag && isDisabledDrag,
231
- 'col--current': currColFlag && currentCol === column
232
- },
233
- headerClassName ? (XEUtils.isFunction(headerClassName) ? headerClassName(cellParams) : headerClassName) : '',
234
- headerCellClassName ? (XEUtils.isFunction(headerCellClassName) ? headerCellClassName(cellParams) : headerCellClassName) : ''
235
- ],
236
- style: headerCellStyle ? (XEUtils.isFunction(headerCellStyle) ? headerCellStyle(cellParams) : headerCellStyle) : null,
237
- ...thAttrs,
238
- ...thOns,
239
- key: showCustomHeader ? `${colid}${$columnIndex}` : (columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex)
240
- }, [
241
- h('div', {
242
- class: ['vxe-cell', {
243
- 'c--title': showTitle,
244
- 'c--tooltip': showTooltip,
245
- 'c--ellipsis': showEllipsis
246
- }],
247
- style: tcStyle
248
- }, isVNPreEmptyStatus || (isOptimizeMode && fixedHiddenColumn)
249
- ? []
250
- : [
251
- h('div', {
252
- colid,
253
- class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
254
- }, column.renderHeader(cellParams))
255
- ]),
256
- /**
257
- * 列宽拖动
258
- */
259
- !fixedHiddenColumn && showResizable && (!showCustomHeader || isLastRow)
260
- ? h('div', {
261
- class: 'vxe-cell--col-resizable',
262
- onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
263
- onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
264
- })
265
- : renderEmptyElement($xeTable)
266
- ])
267
- })
268
- }
269
-
270
- const renderFilterRows = (isOptimizeMode: boolean, cols: VxeTableDefines.ColumnInfo[]) => {
271
- const $xeGrid = $xeTable.xeGrid
272
- const $xeGantt = $xeTable.xeGantt
273
-
274
- const { fixedType } = props
275
- const { showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign } = tableProps
276
- const { overflowX, currColFlag } = tableReactData
277
- const { fullColumnIdData, currentCol } = tableInternalData
278
- const headerTooltipOpts = computeHeaderTooltipOpts.value
279
- const cellOpts = computeCellOpts.value
280
- const defaultRowHeight = computeDefaultRowHeight.value
281
- const headerCellOpts = computeHeaderCellOpts.value
282
- const floatingFilterOpts = computeFloatingFilterOpts.value
283
- const rendererOpts = computeRendererOpts.value
284
- const { cellClassName } = floatingFilterOpts
285
- const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
286
-
287
- return cols.map((column, $columnIndex) => {
288
- const { type, showHeaderOverflow, headerAlign, align, filters, editRender, cellRender, floatingFilters, filterRender, slots } = column
289
- const colid = column.id
290
- const colRest = fullColumnIdData[colid] || {}
291
- const renderOpts = editRender || cellRender
292
- const flSlot = slots ? (slots.floatingFilter || slots['floating-filter']) : null
293
- const compConf = renderOpts && renderOpts.name ? (rendererOpts[renderOpts.name] || renderer.get(renderOpts.name)) : null
294
- const flCompConf = isEnableConf(filterRender) && filterRender.name ? (rendererOpts[filterRender.name] || renderer.get(filterRender.name)) : null
295
- const rtFloatingFilter = flCompConf ? flCompConf.renderTableFloatingFilter : null
296
- const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
297
- const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
298
- const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
299
- const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
300
- const showEllipsis = headOverflow === 'ellipsis'
301
- const showTitle = headOverflow === 'title'
302
- const showTooltip = headOverflow === true ? headerTooltipOpts.mode === 'tooltip' : headOverflow === 'tooltip'
303
- const hasEllipsis = showTitle || showTooltip || showEllipsis
304
- let hasFilter = false
305
- let firstFilterOption: VxeTableDefines.FilterOption | null = null
306
- if (filters) {
307
- firstFilterOption = filters[0] as VxeTableDefines.FilterOption
308
- hasFilter = filters.some((item) => item.checked)
309
- }
310
- const columnIndex = colRest.index
311
- const _columnIndex = colRest._index
312
- const cellParams: VxeTableDefines.CellFloatingFilterParams & {
313
- $table: VxeTableConstructor & VxeTablePrivateMethods
314
- } = {
315
- $table: $xeTable,
316
- $grid: $xeGrid,
317
- $gantt: $xeGantt,
318
- column,
319
- columnIndex,
320
- $columnIndex,
321
- _columnIndex,
322
- option: firstFilterOption as VxeTableDefines.FilterOption,
323
- fixed: fixedType,
324
- source: sourceType,
325
- type: renderType,
326
- isHidden: fixedHiddenColumn,
327
- hasFilter
328
- }
329
- const thAttrs: Record<string, string | number | null> = {
330
- colid
331
- }
332
-
333
- const isLastColumn = $columnIndex === cols.length - 1
334
- const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
335
-
336
- const tcStyle: Record<string, string> = {}
337
- if (hasEllipsis) {
338
- tcStyle.height = `${currCellHeight}px`
339
- } else {
340
- tcStyle.minHeight = `${currCellHeight}px`
341
- }
342
-
343
- return h('th', {
344
- class: ['vxe-table--column vxe-header--column is--floating-filters', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
345
- [`col--${headAlign}`]: headAlign,
346
- [`col--${type}`]: type,
347
- 'col--last': isLastColumn,
348
- 'col--fixed': column.fixed,
349
- 'col--ellipsis': hasEllipsis,
350
- 'fixed--width': !isAutoCellWidth,
351
- 'is--padding': isPadding,
352
- 'is--sortable': column.sortable,
353
- 'col--current': currColFlag && currentCol === column
354
- }
355
- ],
356
- key: colid,
357
- ...thAttrs
358
- }, [
359
- h('div', {
360
- class: ['vxe-cell', '' + (cellClassName || ''), {
361
- 'c--title': showTitle,
362
- 'c--tooltip': showTooltip,
363
- 'c--ellipsis': showEllipsis
364
- }],
365
- style: tcStyle
366
- }, isOptimizeMode && fixedHiddenColumn && !floatingFilters
367
- ? []
368
- : [
369
- h('div', {
370
- colid,
371
- class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
372
- }, flSlot
373
- ? $xeTable.callSlot(flSlot, cellParams)
374
- : (rtFloatingFilter && firstFilterOption
375
- ? getSlotVNs(rtFloatingFilter(filterRender, cellParams as unknown as VxeGlobalRendererHandles.RenderTableFloatingFilterParams))
376
- : []))
377
- ])
378
- ])
379
- })
380
- }
381
-
382
- const renderHeads = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], renderColumnList: VxeTableDefines.ColumnInfo[]) => {
383
- const { fixedType } = props
384
-
385
- const { headerRowClassName, headerRowStyle } = tableProps
386
- const floatingFilterOpts = computeFloatingFilterOpts.value
387
- const rowVNs = headerGroups.map((cols, _rowIndex) => {
388
- const params = { $table: $xeTable, rowIndex: _rowIndex, _rowIndex, $rowIndex: _rowIndex, fixed: fixedType, type: renderType }
389
- return h('tr', {
390
- key: _rowIndex,
391
- class: [
392
- 'vxe-header--row',
393
- headerRowClassName ? (XEUtils.isFunction(headerRowClassName) ? headerRowClassName(params) : headerRowClassName) : ''
394
- ],
395
- style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) : null
396
- }, renderRows(isGroup, isOptimizeMode, headerGroups, _rowIndex, cols))
397
- })
398
-
399
- if (floatingFilterOpts.enabled) {
400
- rowVNs.push(
401
- h('tr', {
402
- key: 'ff',
403
- class: [
404
- 'vxe-header--row is--floating-filters',
405
- '' + (floatingFilterOpts.rowClassName || '')
406
- ]
407
- }, renderFilterRows(isOptimizeMode, renderColumnList))
408
- )
409
- }
410
-
411
- return rowVNs
412
- }
413
-
414
- const renderVN = () => {
415
- const { fixedType, fixedColumn, tableColumn } = props
416
- const { mouseConfig } = tableProps
417
- const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
418
- const { visibleColumn, fullColumnIdData } = tableInternalData
419
-
420
- const mouseOpts = computeMouseOpts.value
421
- const isHeaderRenderOptimize = computeIsHeaderRenderOptimize.value
422
- let renderHeaderList = headerColumn.value || []
423
- let renderColumnList = tableColumn as VxeTableDefines.ColumnInfo[]
424
- const isOptimizeMode = isHeaderRenderOptimize
425
-
426
- if (isGroup) {
427
- renderColumnList = visibleColumn
428
- } else {
429
- if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
430
- renderColumnList = visibleColumn
431
- }
432
-
433
- if (fixedType) {
434
- // 如果是使用优化模式
435
- if (isOptimizeMode) {
436
- renderColumnList = fixedColumn || []
437
- }
438
- }
439
- renderHeaderList = [renderColumnList]
440
- }
441
-
442
- if (!fixedType && !isGroup) {
443
- // 列拖拽
444
- if (scrollXLoad && dragCol) {
445
- if (renderColumnList.length > 2) {
446
- const dCowRest = fullColumnIdData[dragCol.id]
447
- if (dCowRest) {
448
- const dcIndex = dCowRest._index
449
- const firstCol = renderColumnList[0]
450
- const lastCol = renderColumnList[renderColumnList.length - 1]
451
- const firstColRest = fullColumnIdData[firstCol.id]
452
- const lastColRest = fullColumnIdData[lastCol.id]
453
- if (firstColRest && lastColRest) {
454
- const fcIndex = firstColRest._index
455
- const lcIndex = lastColRest._index
456
- if (dcIndex < fcIndex) {
457
- renderColumnList = [dragCol].concat(renderColumnList)
458
- renderHeaderList = [[dragCol].concat(renderHeaderList[0])].concat(renderHeaderList.slice(1))
459
- } else if (dcIndex > lcIndex) {
460
- renderColumnList = renderColumnList.concat([dragCol])
461
- renderHeaderList = [renderHeaderList[0].concat([dragCol])].concat(renderHeaderList.slice(1))
462
- }
463
- }
464
- }
465
- }
466
- }
467
- }
468
-
469
- return h('div', {
470
- ref: refElem,
471
- class: ['vxe-table--header-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
472
- xid: xID
473
- }, [
474
- h('div', {
475
- ref: refHeaderScroll,
476
- class: 'vxe-table--header-inner-wrapper',
477
- onScroll (evnt) {
478
- $xeTable.triggerHeaderScrollEvent(evnt, fixedType)
479
- }
480
- }, [
481
- fixedType
482
- ? renderEmptyElement($xeTable)
483
- : h('div', {
484
- ref: refHeaderXSpace,
485
- class: 'vxe-body--x-space'
486
- }),
487
- h('table', {
488
- ref: refHeaderTable,
489
- class: 'vxe-table--header',
490
- xid: xID,
491
- cellspacing: 0,
492
- cellpadding: 0,
493
- border: 0,
494
- xvm: isOptimizeMode ? '1' : null
495
- }, [
496
- /**
497
- * 列宽
498
- */
499
- h('colgroup', {
500
- ref: refHeaderColgroup
501
- }, renderColumnList.map((column, $columnIndex) => {
502
- return h('col', {
503
- name: column.id,
504
- key: $columnIndex,
505
- style: {
506
- width: `${column.renderWidth}px`
507
- }
508
- })
509
- })),
510
- /**
511
- * 头部
512
- */
513
- h('thead', {
514
- ref: refHeaderTHead
515
- }, renderHeads(isGroup, isOptimizeMode, renderHeaderList, renderColumnList))
516
- ]),
517
- hasEnableConf(mouseConfig, mouseOpts) && mouseOpts.area
518
- ? h('div', {
519
- class: 'vxe-table--cell-area',
520
- xid: xID
521
- }, [
522
- h('span', {
523
- class: 'vxe-table--cell-main-area'
524
- }),
525
- h('span', {
526
- class: 'vxe-table--cell-clip-area'
527
- }),
528
- h('span', {
529
- class: 'vxe-table--cell-extend-area'
530
- }),
531
- h('span', {
532
- class: 'vxe-table--cell-multi-area'
533
- }),
534
- h('span', {
535
- class: 'vxe-table--cell-active-area'
536
- }),
537
- h('span', {
538
- class: 'vxe-table--cell-col-status-area'
539
- })
540
- ])
541
- : renderEmptyElement($xeTable)
542
- ])
543
- ])
544
- }
545
-
546
- watch(() => props.tableColumn, uploadColumn)
547
-
548
- onMounted(() => {
549
- nextTick(() => {
550
- const { fixedType } = props
551
- const { internalData } = $xeTable
552
- const { elemStore } = internalData
553
- const prefix = `${fixedType || 'main'}-header-`
554
- elemStore[`${prefix}wrapper`] = refElem
555
- elemStore[`${prefix}scroll`] = refHeaderScroll
556
- elemStore[`${prefix}table`] = refHeaderTable
557
- elemStore[`${prefix}colgroup`] = refHeaderColgroup
558
- elemStore[`${prefix}list`] = refHeaderTHead
559
- elemStore[`${prefix}xSpace`] = refHeaderXSpace
560
- elemStore[`${prefix}repair`] = refHeaderBorderRepair
561
- uploadColumn()
562
- })
563
- })
564
-
565
- onUnmounted(() => {
566
- const { fixedType } = props
567
- const { internalData } = $xeTable
568
- const { elemStore } = internalData
569
- const prefix = `${fixedType || 'main'}-header-`
570
- elemStore[`${prefix}wrapper`] = null
571
- elemStore[`${prefix}scroll`] = null
572
- elemStore[`${prefix}table`] = null
573
- elemStore[`${prefix}colgroup`] = null
574
- elemStore[`${prefix}list`] = null
575
- elemStore[`${prefix}xSpace`] = null
576
- elemStore[`${prefix}repair`] = null
577
- })
578
-
579
- return renderVN
580
- }
581
- })
1
+ import { h, ref, Ref, PropType, inject, nextTick, watch, 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 { getDefaultConfig, hasEnableConf, isEnableConf } from '../../ui/src/utils'
6
+ import { getCalcHeight, convertHeaderColumnToRows, convertHeaderToGridRows } from './util'
7
+ import { getSlotVNs } from '../../ui/src/vn'
8
+
9
+ import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines, VxeGlobalRendererHandles } from '../../../types'
10
+
11
+ const { renderer, renderEmptyElement } = VxeUI
12
+
13
+ const sourceType = 'table'
14
+ const renderType = 'header'
15
+
16
+ export default defineVxeComponent({
17
+ name: 'VxeTableHeader',
18
+ props: {
19
+ tableData: Array as PropType<any[]>,
20
+ tableColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
21
+ tableGroupColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
22
+ fixedColumn: Array as PropType<VxeTableDefines.ColumnInfo[]>,
23
+ fixedType: {
24
+ type: String as PropType<'right' | 'left' | ''>,
25
+ default: null
26
+ }
27
+ },
28
+ setup(props) {
29
+ const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)
30
+
31
+ const { xID, props: tableProps, reactData: tableReactData, internalData: tableInternalData } = $xeTable
32
+ const { computeColumnOpts, computeColumnDragOpts, computeCellOpts, computeMouseOpts, computeHeaderCellOpts, computeDefaultRowHeight, computeVirtualXOpts, computeFloatingFilterOpts, computeIsHeaderRenderOptimize, computeHeaderTooltipOpts, computeRendererOpts } = $xeTable.getComputeMaps()
33
+
34
+ const headerColumn = ref<VxeTableDefines.ColumnInfo[][]>([])
35
+
36
+ const refElem = ref() as Ref<HTMLDivElement>
37
+ const refHeaderScroll = ref() as Ref<HTMLDivElement>
38
+ const refHeaderTable = ref() as Ref<HTMLTableElement>
39
+ const refHeaderColgroup = ref() as Ref<HTMLTableColElement>
40
+ const refHeaderTHead = ref() as Ref<HTMLTableSectionElement>
41
+ const refHeaderXSpace = ref() as Ref<HTMLDivElement>
42
+ const refHeaderBorderRepair = ref() as Ref<HTMLDivElement>
43
+
44
+ const uploadColumn = () => {
45
+ const { showCustomHeader } = tableProps
46
+ const { collectColumn, visibleColumn } = tableInternalData
47
+ const { tableGroupColumn } = props
48
+ const { isGroup } = tableReactData
49
+ let spanColumns: VxeTableDefines.ColumnInfo[][] = isGroup ? convertHeaderColumnToRows(tableGroupColumn) : []
50
+ let visibleColgroups: VxeTableDefines.ColumnInfo[][] = []
51
+ if (showCustomHeader && spanColumns.length > 1) {
52
+ visibleColgroups = convertHeaderToGridRows(spanColumns)
53
+ spanColumns = visibleColgroups
54
+ }
55
+ headerColumn.value = spanColumns
56
+ nextTick(() => {
57
+ $xeTable.dispatchEvent('columns-change', { visibleColgroups, collectColumn, visibleColumn }, null)
58
+ })
59
+ }
60
+
61
+ const renderRows = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], _rowIndex: number, cols: VxeTableDefines.ColumnInfo[]) => {
62
+ const $xeGrid = $xeTable.xeGrid
63
+ const $xeGantt = $xeTable.xeGantt
64
+
65
+ const { fixedType } = props
66
+ const { resizable: allResizable, columnKey, showCustomHeader, headerCellClassName, headerCellStyle, showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign, mouseConfig } = tableProps
67
+ const { dragCol, scrollXLoad, scrollYLoad, overflowX, mergeHeadFlag, tableColumn, currColFlag } = tableReactData
68
+ const { fullColumnIdData, scrollXStore, mergeHeaderList, mergeHeaderCellMaps, currentCol } = tableInternalData
69
+ const virtualXOpts = computeVirtualXOpts.value
70
+ const columnOpts = computeColumnOpts.value
71
+ const columnDragOpts = computeColumnDragOpts.value
72
+ const headerTooltipOpts = computeHeaderTooltipOpts.value
73
+ const cellOpts = computeCellOpts.value
74
+ const defaultRowHeight = computeDefaultRowHeight.value
75
+ const headerCellOpts = computeHeaderCellOpts.value
76
+ const rendererOpts = computeRendererOpts.value
77
+ const mouseOpts = computeMouseOpts.value
78
+ const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
79
+ const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = columnDragOpts
80
+ const isLastRow = _rowIndex === headerGroups.length - 1
81
+
82
+ return cols.map((column, $columnIndex) => {
83
+ const { type, showHeaderOverflow, headerAlign, align, filters, headerClassName, editRender, cellRender } = column
84
+ const colid = column.id
85
+ const colRest = fullColumnIdData[colid] || {}
86
+ const renderOpts = editRender || cellRender
87
+ const compConf = renderOpts && renderOpts.name ? rendererOpts[renderOpts.name] || renderer.get(renderOpts.name) : null
88
+ const isColGroup = column.children && column.children.length
89
+ const fixedHiddenColumn = overflowX && !isColGroup && (fixedType ? column.fixed !== fixedType : !!column.fixed)
90
+
91
+ const cellPadding = getDefaultConfig(headerCellOpts.padding, cellOpts.padding)
92
+ const isAllCellPadding = cellPadding === true
93
+ const isCellPaddingTop = cellPadding ? isAllCellPadding || cellPadding.top !== false : false
94
+ const isCellPaddingBottom = cellPadding ? isAllCellPadding || cellPadding.bottom !== false : false
95
+ const isCellPaddingLeft = cellPadding ? isAllCellPadding || cellPadding.left !== false : false
96
+ const isCellPaddingRight = cellPadding ? isAllCellPadding || cellPadding.right !== false : false
97
+
98
+ const headOverflow = getDefaultConfig(showHeaderOverflow, allColumnHeaderOverflow)
99
+ const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
100
+ const showEllipsis = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'ellipsis'
101
+ const showTitle = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'title'
102
+ const showTooltip = (headOverflow === true ? headerTooltipOpts.mode : headOverflow) === 'tooltip'
103
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
104
+ let hasFilter = false
105
+ let firstFilterOption: VxeTableDefines.FilterOption | null = null
106
+ if (filters) {
107
+ firstFilterOption = filters[0] as VxeTableDefines.FilterOption
108
+ hasFilter = filters.some((item) => item.checked)
109
+ }
110
+ const columnIndex = colRest.index
111
+ const _columnIndex = colRest._index
112
+ const cellParams: VxeTableDefines.CellRenderHeaderParams & {
113
+ $table: VxeTableConstructor & VxeTablePrivateMethods
114
+ } = {
115
+ $table: $xeTable,
116
+ $grid: $xeGrid,
117
+ $gantt: $xeGantt,
118
+ rowIndex: _rowIndex,
119
+ _rowIndex,
120
+ $rowIndex: _rowIndex,
121
+ column,
122
+ columnIndex,
123
+ $columnIndex,
124
+ _columnIndex,
125
+ firstFilterOption: firstFilterOption as VxeTableDefines.FilterOption,
126
+ fixed: fixedType,
127
+ source: sourceType,
128
+ type: renderType,
129
+ isHidden: fixedHiddenColumn,
130
+ hasFilter
131
+ }
132
+ const thAttrs: Record<string, string | number | null> = {
133
+ colid
134
+ }
135
+ let isMergeCell = false
136
+ // 合并行或列
137
+ if (!showCustomHeader) {
138
+ thAttrs.colspan = column.colSpan > 1 ? column.colSpan : null
139
+ thAttrs.rowspan = column.rowSpan > 1 ? column.rowSpan : null
140
+ }
141
+ if (mergeHeadFlag && mergeHeaderList.length && (showCustomHeader || isLastRow)) {
142
+ const spanRest = mergeHeaderCellMaps[`${_rowIndex}:${showCustomHeader ? $columnIndex : _columnIndex}`]
143
+ if (spanRest) {
144
+ const { rowspan, colspan } = spanRest
145
+ if (!rowspan || !colspan) {
146
+ return null
147
+ }
148
+ if (rowspan > 1) {
149
+ isMergeCell = true
150
+ thAttrs.rowspan = rowspan
151
+ }
152
+ if (colspan > 1) {
153
+ isMergeCell = true
154
+ thAttrs.colspan = colspan
155
+ }
156
+ }
157
+ }
158
+
159
+ const thOns: any = {
160
+ onClick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellClickEvent(evnt, cellParams),
161
+ onDblclick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellDblclickEvent(evnt, cellParams)
162
+ }
163
+ const isColDragCell = columnOpts.drag && columnDragOpts.trigger === 'cell'
164
+ let isDisabledDrag = false
165
+ if (isColDragCell) {
166
+ isDisabledDrag = !!(dragDisabledMethod && dragDisabledMethod(cellParams))
167
+ }
168
+ // 按下事件处理
169
+ if (hasEnableConf(mouseConfig, mouseOpts) || isColDragCell) {
170
+ thOns.onMousedown = (evnt: MouseEvent) => $xeTable.triggerHeaderCellMousedownEvent(evnt, cellParams)
171
+ }
172
+ // 拖拽列事件
173
+ if (columnOpts.drag) {
174
+ thOns.onDragstart = $xeTable.handleHeaderCellDragDragstartEvent
175
+ thOns.onDragend = $xeTable.handleHeaderCellDragDragendEvent
176
+ thOns.onDragover = $xeTable.handleHeaderCellDragDragoverEvent
177
+ if (isColDragCell) {
178
+ thOns.onMouseup = $xeTable.handleHeaderCellDragMouseupEvent
179
+ }
180
+ }
181
+ const isLastColumn = $columnIndex === cols.length - 1
182
+ const showResizable = XEUtils.isBoolean(column.resizable) ? column.resizable : columnOpts.resizable || allResizable
183
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
184
+
185
+ let isVNPreEmptyStatus = false
186
+ if (isOptimizeMode && overflowX && !isGroup && !isMergeCell) {
187
+ if (!dragCol || dragCol.id !== colid) {
188
+ if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
189
+ isVNPreEmptyStatus = true
190
+ }
191
+ }
192
+ }
193
+
194
+ const tcStyle: Record<string, string> = {}
195
+ if (hasEllipsis) {
196
+ tcStyle.height = `${currCellHeight}px`
197
+ } else {
198
+ tcStyle.minHeight = `${currCellHeight}px`
199
+ }
200
+
201
+ if (showCustomHeader) {
202
+ // custom
203
+ } else if (isColGroup && !isLastRow) {
204
+ let childWidth = 0
205
+ XEUtils.eachTree(column.children, (childRow) => {
206
+ if (childRow.visible && (!childRow.children || !childRow.children.length)) {
207
+ childWidth += childRow.renderWidth
208
+ }
209
+ })
210
+ tcStyle.width = `${childWidth}px`
211
+ }
212
+
213
+ return h(
214
+ 'th',
215
+ {
216
+ class: [
217
+ 'vxe-table--column vxe-header--column',
218
+ colid,
219
+ fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible',
220
+ {
221
+ [`col--${headAlign}`]: headAlign,
222
+ [`col--${type}`]: type,
223
+ 'col--last': isLastColumn,
224
+ 'col--fixed': column.fixed,
225
+ 'col--group': isColGroup,
226
+ 'col--ellipsis': hasEllipsis,
227
+ 'fixed--width': !isAutoCellWidth,
228
+ 'is--pg-top': isCellPaddingTop,
229
+ 'is--pg-bottom': isCellPaddingBottom,
230
+ 'is--pg-left': isCellPaddingLeft,
231
+ 'is--pg-right': isCellPaddingRight,
232
+ 'is--sortable': column.sortable,
233
+ 'col--filter': !!filters,
234
+ 'is--filter-active': hasFilter,
235
+ 'is--drag-active': columnOpts.drag && !column.fixed && !isDisabledDrag && (isCrossDrag || isPeerDrag || !column.parentId),
236
+ 'is--drag-disabled': columnOpts.drag && isDisabledDrag,
237
+ 'col--current': currColFlag && currentCol === column
238
+ },
239
+ headerClassName ? (XEUtils.isFunction(headerClassName) ? headerClassName(cellParams) : headerClassName) : '',
240
+ headerCellClassName ? (XEUtils.isFunction(headerCellClassName) ? headerCellClassName(cellParams) : headerCellClassName) : ''
241
+ ],
242
+ style: headerCellStyle ? (XEUtils.isFunction(headerCellStyle) ? headerCellStyle(cellParams) : headerCellStyle) : null,
243
+ ...thAttrs,
244
+ ...thOns,
245
+ key: showCustomHeader ? `${colid}${$columnIndex}` : columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex
246
+ },
247
+ [
248
+ h(
249
+ 'div',
250
+ {
251
+ class: [
252
+ 'vxe-cell',
253
+ {
254
+ 'c--title': showTitle,
255
+ 'c--tooltip': showTooltip,
256
+ 'c--ellipsis': showEllipsis
257
+ }
258
+ ],
259
+ style: tcStyle
260
+ },
261
+ isVNPreEmptyStatus || (isOptimizeMode && fixedHiddenColumn)
262
+ ? []
263
+ : [
264
+ h(
265
+ 'div',
266
+ {
267
+ colid,
268
+ class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
269
+ },
270
+ column.renderHeader(cellParams)
271
+ )
272
+ ]
273
+ ),
274
+ /**
275
+ * 列宽拖动
276
+ */
277
+ !fixedHiddenColumn && showResizable && (!showCustomHeader || isLastRow)
278
+ ? h('div', {
279
+ class: 'vxe-cell--col-resizable',
280
+ onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
281
+ onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
282
+ })
283
+ : renderEmptyElement($xeTable)
284
+ ]
285
+ )
286
+ })
287
+ }
288
+
289
+ const renderFilterRows = (isOptimizeMode: boolean, cols: VxeTableDefines.ColumnInfo[]) => {
290
+ const $xeGrid = $xeTable.xeGrid
291
+ const $xeGantt = $xeTable.xeGantt
292
+
293
+ const { fixedType } = props
294
+ const { showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign } = tableProps
295
+ const { overflowX, currColFlag } = tableReactData
296
+ const { fullColumnIdData, currentCol } = tableInternalData
297
+ const headerTooltipOpts = computeHeaderTooltipOpts.value
298
+ const cellOpts = computeCellOpts.value
299
+ const defaultRowHeight = computeDefaultRowHeight.value
300
+ const headerCellOpts = computeHeaderCellOpts.value
301
+ const floatingFilterOpts = computeFloatingFilterOpts.value
302
+ const rendererOpts = computeRendererOpts.value
303
+ const { cellClassName } = floatingFilterOpts
304
+ const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
305
+
306
+ return cols.map((column, $columnIndex) => {
307
+ const { type, showHeaderOverflow, headerAlign, align, filters, editRender, cellRender, floatingFilters, filterRender, slots } = column
308
+ const colid = column.id
309
+ const colRest = fullColumnIdData[colid] || {}
310
+ const renderOpts = editRender || cellRender
311
+ const flSlot = slots ? slots.floatingFilter || slots['floating-filter'] : null
312
+ const compConf = renderOpts && renderOpts.name ? rendererOpts[renderOpts.name] || renderer.get(renderOpts.name) : null
313
+ const flCompConf = isEnableConf(filterRender) && filterRender.name ? rendererOpts[filterRender.name] || renderer.get(filterRender.name) : null
314
+ const rtFloatingFilter = flCompConf ? flCompConf.renderTableFloatingFilter : null
315
+ const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
316
+ const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
317
+ const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
318
+ const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
319
+ const showEllipsis = headOverflow === 'ellipsis'
320
+ const showTitle = headOverflow === 'title'
321
+ const showTooltip = headOverflow === true ? headerTooltipOpts.mode === 'tooltip' : headOverflow === 'tooltip'
322
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
323
+ let hasFilter = false
324
+ let firstFilterOption: VxeTableDefines.FilterOption | null = null
325
+ if (filters) {
326
+ firstFilterOption = filters[0] as VxeTableDefines.FilterOption
327
+ hasFilter = filters.some((item) => item.checked)
328
+ }
329
+ const columnIndex = colRest.index
330
+ const _columnIndex = colRest._index
331
+ const cellParams: VxeTableDefines.CellFloatingFilterParams & {
332
+ $table: VxeTableConstructor & VxeTablePrivateMethods
333
+ } = {
334
+ $table: $xeTable,
335
+ $grid: $xeGrid,
336
+ $gantt: $xeGantt,
337
+ column,
338
+ columnIndex,
339
+ $columnIndex,
340
+ _columnIndex,
341
+ option: firstFilterOption as VxeTableDefines.FilterOption,
342
+ fixed: fixedType,
343
+ source: sourceType,
344
+ type: renderType,
345
+ isHidden: fixedHiddenColumn,
346
+ hasFilter
347
+ }
348
+ const thAttrs: Record<string, string | number | null> = {
349
+ colid
350
+ }
351
+
352
+ const isLastColumn = $columnIndex === cols.length - 1
353
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
354
+
355
+ const tcStyle: Record<string, string> = {}
356
+ if (hasEllipsis) {
357
+ tcStyle.height = `${currCellHeight}px`
358
+ } else {
359
+ tcStyle.minHeight = `${currCellHeight}px`
360
+ }
361
+
362
+ return h(
363
+ 'th',
364
+ {
365
+ class: [
366
+ 'vxe-table--column vxe-header--column is--floating-filters',
367
+ colid,
368
+ fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible',
369
+ {
370
+ [`col--${headAlign}`]: headAlign,
371
+ [`col--${type}`]: type,
372
+ 'col--last': isLastColumn,
373
+ 'col--fixed': column.fixed,
374
+ 'col--ellipsis': hasEllipsis,
375
+ 'fixed--width': !isAutoCellWidth,
376
+ 'is--padding': isPadding,
377
+ 'is--sortable': column.sortable,
378
+ 'col--current': currColFlag && currentCol === column
379
+ }
380
+ ],
381
+ key: colid,
382
+ ...thAttrs
383
+ },
384
+ [
385
+ h(
386
+ 'div',
387
+ {
388
+ class: [
389
+ 'vxe-cell',
390
+ '' + (cellClassName || ''),
391
+ {
392
+ 'c--title': showTitle,
393
+ 'c--tooltip': showTooltip,
394
+ 'c--ellipsis': showEllipsis
395
+ }
396
+ ],
397
+ style: tcStyle
398
+ },
399
+ isOptimizeMode && fixedHiddenColumn && !floatingFilters
400
+ ? []
401
+ : [
402
+ h(
403
+ 'div',
404
+ {
405
+ colid,
406
+ class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
407
+ },
408
+ flSlot ? $xeTable.callSlot(flSlot, cellParams) : rtFloatingFilter && firstFilterOption ? getSlotVNs(rtFloatingFilter(filterRender, cellParams as unknown as VxeGlobalRendererHandles.RenderTableFloatingFilterParams)) : []
409
+ )
410
+ ]
411
+ )
412
+ ]
413
+ )
414
+ })
415
+ }
416
+
417
+ const renderHeads = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], renderColumnList: VxeTableDefines.ColumnInfo[]) => {
418
+ const { fixedType } = props
419
+
420
+ const { headerRowClassName, headerRowStyle } = tableProps
421
+ const floatingFilterOpts = computeFloatingFilterOpts.value
422
+ const rowVNs = headerGroups.map((cols, _rowIndex) => {
423
+ const params = { $table: $xeTable, rowIndex: _rowIndex, _rowIndex, $rowIndex: _rowIndex, fixed: fixedType, type: renderType }
424
+ return h(
425
+ 'tr',
426
+ {
427
+ key: _rowIndex,
428
+ class: ['vxe-header--row', headerRowClassName ? (XEUtils.isFunction(headerRowClassName) ? headerRowClassName(params) : headerRowClassName) : ''],
429
+ style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) : null
430
+ },
431
+ renderRows(isGroup, isOptimizeMode, headerGroups, _rowIndex, cols)
432
+ )
433
+ })
434
+
435
+ if (floatingFilterOpts.enabled) {
436
+ rowVNs.push(
437
+ h(
438
+ 'tr',
439
+ {
440
+ key: 'ff',
441
+ class: ['vxe-header--row is--floating-filters', '' + (floatingFilterOpts.rowClassName || '')]
442
+ },
443
+ renderFilterRows(isOptimizeMode, renderColumnList)
444
+ )
445
+ )
446
+ }
447
+
448
+ return rowVNs
449
+ }
450
+
451
+ const renderVN = () => {
452
+ const { fixedType, fixedColumn, tableColumn } = props
453
+ const { mouseConfig } = tableProps
454
+ const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
455
+ const { visibleColumn, fullColumnIdData } = tableInternalData
456
+
457
+ const mouseOpts = computeMouseOpts.value
458
+ const isHeaderRenderOptimize = computeIsHeaderRenderOptimize.value
459
+ let renderHeaderList = headerColumn.value || []
460
+ let renderColumnList = tableColumn as VxeTableDefines.ColumnInfo[]
461
+ const isOptimizeMode = isHeaderRenderOptimize
462
+
463
+ if (isGroup) {
464
+ renderColumnList = visibleColumn
465
+ } else {
466
+ if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
467
+ renderColumnList = visibleColumn
468
+ }
469
+
470
+ if (fixedType) {
471
+ // 如果是使用优化模式
472
+ if (isOptimizeMode) {
473
+ renderColumnList = fixedColumn || []
474
+ }
475
+ }
476
+ renderHeaderList = [renderColumnList]
477
+ }
478
+
479
+ if (!fixedType && !isGroup) {
480
+ // 列拖拽
481
+ if (scrollXLoad && dragCol) {
482
+ if (renderColumnList.length > 2) {
483
+ const dCowRest = fullColumnIdData[dragCol.id]
484
+ if (dCowRest) {
485
+ const dcIndex = dCowRest._index
486
+ const firstCol = renderColumnList[0]
487
+ const lastCol = renderColumnList[renderColumnList.length - 1]
488
+ const firstColRest = fullColumnIdData[firstCol.id]
489
+ const lastColRest = fullColumnIdData[lastCol.id]
490
+ if (firstColRest && lastColRest) {
491
+ const fcIndex = firstColRest._index
492
+ const lcIndex = lastColRest._index
493
+ if (dcIndex < fcIndex) {
494
+ renderColumnList = [dragCol].concat(renderColumnList)
495
+ renderHeaderList = [[dragCol].concat(renderHeaderList[0])].concat(renderHeaderList.slice(1))
496
+ } else if (dcIndex > lcIndex) {
497
+ renderColumnList = renderColumnList.concat([dragCol])
498
+ renderHeaderList = [renderHeaderList[0].concat([dragCol])].concat(renderHeaderList.slice(1))
499
+ }
500
+ }
501
+ }
502
+ }
503
+ }
504
+ }
505
+
506
+ return h(
507
+ 'div',
508
+ {
509
+ ref: refElem,
510
+ class: ['vxe-table--header-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
511
+ xid: xID
512
+ },
513
+ [
514
+ h(
515
+ 'div',
516
+ {
517
+ ref: refHeaderScroll,
518
+ class: 'vxe-table--header-inner-wrapper',
519
+ onScroll(evnt) {
520
+ $xeTable.triggerHeaderScrollEvent(evnt, fixedType)
521
+ }
522
+ },
523
+ [
524
+ fixedType
525
+ ? renderEmptyElement($xeTable)
526
+ : h('div', {
527
+ ref: refHeaderXSpace,
528
+ class: 'vxe-body--x-space'
529
+ }),
530
+ h(
531
+ 'table',
532
+ {
533
+ ref: refHeaderTable,
534
+ class: 'vxe-table--header',
535
+ xid: xID,
536
+ cellspacing: 0,
537
+ cellpadding: 0,
538
+ border: 0,
539
+ xvm: isOptimizeMode ? '1' : null
540
+ },
541
+ [
542
+ /**
543
+ * 列宽
544
+ */
545
+ h(
546
+ 'colgroup',
547
+ {
548
+ ref: refHeaderColgroup
549
+ },
550
+ renderColumnList.map((column, $columnIndex) => {
551
+ return h('col', {
552
+ name: column.id,
553
+ key: $columnIndex,
554
+ style: {
555
+ width: `${column.renderWidth}px`
556
+ }
557
+ })
558
+ })
559
+ ),
560
+ /**
561
+ * 头部
562
+ */
563
+ h(
564
+ 'thead',
565
+ {
566
+ ref: refHeaderTHead
567
+ },
568
+ renderHeads(isGroup, isOptimizeMode, renderHeaderList, renderColumnList)
569
+ )
570
+ ]
571
+ ),
572
+ hasEnableConf(mouseConfig, mouseOpts) && mouseOpts.area
573
+ ? h(
574
+ 'div',
575
+ {
576
+ class: 'vxe-table--cell-area',
577
+ xid: xID
578
+ },
579
+ [
580
+ h('span', {
581
+ class: 'vxe-table--cell-main-area'
582
+ }),
583
+ h('span', {
584
+ class: 'vxe-table--cell-clip-area'
585
+ }),
586
+ h('span', {
587
+ class: 'vxe-table--cell-extend-area'
588
+ }),
589
+ h('span', {
590
+ class: 'vxe-table--cell-multi-area'
591
+ }),
592
+ h('span', {
593
+ class: 'vxe-table--cell-active-area'
594
+ }),
595
+ h('span', {
596
+ class: 'vxe-table--cell-col-status-area'
597
+ })
598
+ ]
599
+ )
600
+ : renderEmptyElement($xeTable)
601
+ ]
602
+ )
603
+ ]
604
+ )
605
+ }
606
+
607
+ watch(() => props.tableColumn, uploadColumn)
608
+
609
+ onMounted(() => {
610
+ nextTick(() => {
611
+ const { fixedType } = props
612
+ const { internalData } = $xeTable
613
+ const { elemStore } = internalData
614
+ const prefix = `${fixedType || 'main'}-header-`
615
+ elemStore[`${prefix}wrapper`] = refElem
616
+ elemStore[`${prefix}scroll`] = refHeaderScroll
617
+ elemStore[`${prefix}table`] = refHeaderTable
618
+ elemStore[`${prefix}colgroup`] = refHeaderColgroup
619
+ elemStore[`${prefix}list`] = refHeaderTHead
620
+ elemStore[`${prefix}xSpace`] = refHeaderXSpace
621
+ elemStore[`${prefix}repair`] = refHeaderBorderRepair
622
+ uploadColumn()
623
+ })
624
+ })
625
+
626
+ onUnmounted(() => {
627
+ const { fixedType } = props
628
+ const { internalData } = $xeTable
629
+ const { elemStore } = internalData
630
+ const prefix = `${fixedType || 'main'}-header-`
631
+ elemStore[`${prefix}wrapper`] = null
632
+ elemStore[`${prefix}scroll`] = null
633
+ elemStore[`${prefix}table`] = null
634
+ elemStore[`${prefix}colgroup`] = null
635
+ elemStore[`${prefix}list`] = null
636
+ elemStore[`${prefix}xSpace`] = null
637
+ elemStore[`${prefix}repair`] = null
638
+ })
639
+
640
+ return renderVN
641
+ }
642
+ })