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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +20 -20
  2. package/README.en.md +118 -118
  3. package/README.ja-JP.md +117 -117
  4. package/README.md +268 -268
  5. package/README.zh-TW.md +117 -117
  6. package/es/style.css +1 -1
  7. package/es/table/render/index.js +1 -1
  8. package/es/ui/index.js +1 -1
  9. package/es/ui/src/log.js +1 -1
  10. package/lib/index.umd.js +2767 -2851
  11. package/lib/index.umd.min.js +1 -1
  12. package/lib/style.css +1 -1
  13. package/lib/table/render/index.js +1 -1
  14. package/lib/table/render/index.min.js +1 -1
  15. package/lib/ui/index.js +1 -1
  16. package/lib/ui/index.min.js +1 -1
  17. package/lib/ui/src/log.js +1 -1
  18. package/lib/ui/src/log.min.js +1 -1
  19. package/package.json +92 -92
  20. package/packages/colgroup/index.ts +22 -22
  21. package/packages/column/index.ts +22 -22
  22. package/packages/components.ts +43 -43
  23. package/packages/grid/index.ts +18 -18
  24. package/packages/grid/src/emits.ts +19 -19
  25. package/packages/grid/src/grid.ts +1768 -1768
  26. package/packages/grid/src/props.ts +23 -23
  27. package/packages/index.ts +4 -4
  28. package/packages/locale/lang/ar-EG.ts +840 -840
  29. package/packages/locale/lang/de-DE.ts +840 -840
  30. package/packages/locale/lang/en-US.ts +840 -840
  31. package/packages/locale/lang/es-ES.ts +840 -840
  32. package/packages/locale/lang/fr-FR.ts +840 -840
  33. package/packages/locale/lang/hu-HU.ts +840 -840
  34. package/packages/locale/lang/hy-AM.ts +840 -840
  35. package/packages/locale/lang/id-ID.ts +840 -840
  36. package/packages/locale/lang/it-IT.ts +840 -840
  37. package/packages/locale/lang/ja-JP.ts +840 -840
  38. package/packages/locale/lang/ko-KR.ts +840 -840
  39. package/packages/locale/lang/ms-MY.ts +840 -840
  40. package/packages/locale/lang/nb-NO.ts +840 -840
  41. package/packages/locale/lang/pt-BR.ts +840 -840
  42. package/packages/locale/lang/ru-RU.ts +840 -840
  43. package/packages/locale/lang/th-TH.ts +840 -840
  44. package/packages/locale/lang/ug-CN.ts +840 -840
  45. package/packages/locale/lang/uk-UA.ts +840 -840
  46. package/packages/locale/lang/uz-UZ.ts +840 -840
  47. package/packages/locale/lang/vi-VN.ts +840 -840
  48. package/packages/locale/lang/zh-CHT.ts +840 -840
  49. package/packages/locale/lang/zh-CN.ts +840 -840
  50. package/packages/locale/lang/zh-HK.ts +3 -3
  51. package/packages/locale/lang/zh-MO.ts +3 -3
  52. package/packages/locale/lang/zh-TC.ts +3 -3
  53. package/packages/locale/lang/zh-TW.ts +3 -3
  54. package/packages/table/index.ts +26 -26
  55. package/packages/table/module/custom/hook.ts +422 -422
  56. package/packages/table/module/custom/panel.ts +1512 -1512
  57. package/packages/table/module/edit/hook.ts +1064 -1064
  58. package/packages/table/module/export/export-panel.ts +567 -567
  59. package/packages/table/module/export/hook.ts +1654 -1654
  60. package/packages/table/module/export/import-panel.ts +266 -266
  61. package/packages/table/module/export/util.ts +24 -24
  62. package/packages/table/module/filter/hook.ts +468 -468
  63. package/packages/table/module/filter/panel.ts +301 -301
  64. package/packages/table/module/keyboard/hook.ts +494 -494
  65. package/packages/table/module/menu/hook.ts +325 -325
  66. package/packages/table/module/menu/panel.ts +201 -201
  67. package/packages/table/module/validator/hook.ts +631 -631
  68. package/packages/table/render/index.ts +1440 -1440
  69. package/packages/table/src/body.ts +935 -935
  70. package/packages/table/src/cell.ts +1290 -1290
  71. package/packages/table/src/column.ts +190 -190
  72. package/packages/table/src/columnInfo.ts +225 -225
  73. package/packages/table/src/emits.ts +125 -125
  74. package/packages/table/src/footer.ts +368 -368
  75. package/packages/table/src/group.ts +59 -59
  76. package/packages/table/src/header.ts +561 -561
  77. package/packages/table/src/props.ts +324 -324
  78. package/packages/table/src/store.ts +14 -14
  79. package/packages/table/src/table.ts +14274 -14274
  80. package/packages/table/src/use/cell-view.ts +44 -44
  81. package/packages/table/src/use/index.ts +1 -1
  82. package/packages/table/src/util.ts +1086 -1086
  83. package/packages/toolbar/index.ts +18 -18
  84. package/packages/toolbar/src/toolbar.ts +701 -701
  85. package/packages/ui/index.ts +532 -532
  86. package/packages/ui/src/anime.ts +52 -52
  87. package/packages/ui/src/comp.ts +3 -3
  88. package/packages/ui/src/dom.ts +264 -264
  89. package/packages/ui/src/log.ts +8 -8
  90. package/packages/ui/src/utils.ts +56 -56
  91. package/packages/ui/src/vn.ts +55 -55
  92. package/packages/v-x-e-table/index.d.ts +4 -4
  93. package/packages/v-x-e-table/index.ts +4 -4
  94. package/styles/all.scss +7 -7
  95. package/styles/base.scss +16 -16
  96. package/styles/components/grid.scss +89 -89
  97. package/styles/components/icon.scss +225 -225
  98. package/styles/components/old-icon.scss +715 -715
  99. package/styles/components/table-module/all.scss +6 -6
  100. package/styles/components/table-module/custom.scss +550 -550
  101. package/styles/components/table-module/export.scss +130 -130
  102. package/styles/components/table-module/filter.scss +130 -130
  103. package/styles/components/table-module/menu.scss +81 -81
  104. package/styles/components/table.scss +2679 -2679
  105. package/styles/components/toolbar.scss +119 -119
  106. package/styles/default.scss +2 -2
  107. package/styles/helpers/baseMixin.scss +95 -95
  108. package/styles/index.scss +4 -4
  109. package/styles/modules.scss +5 -5
  110. package/styles/theme/base.scss +93 -93
  111. package/styles/theme/dark.scss +49 -49
  112. package/styles/theme/light.scss +44 -44
  113. package/styles/variable.scss +43 -43
  114. package/types/all.d.ts +37 -37
  115. package/types/index.d.ts +4 -4
  116. /package/es/{iconfont.1778157083004.ttf → iconfont.1778318183872.ttf} +0 -0
  117. /package/es/{iconfont.1778157083004.woff → iconfont.1778318183872.woff} +0 -0
  118. /package/es/{iconfont.1778157083004.woff2 → iconfont.1778318183872.woff2} +0 -0
  119. /package/lib/{iconfont.1778157083004.ttf → iconfont.1778318183872.ttf} +0 -0
  120. /package/lib/{iconfont.1778157083004.woff → iconfont.1778318183872.woff} +0 -0
  121. /package/lib/{iconfont.1778157083004.woff2 → iconfont.1778318183872.woff2} +0 -0
@@ -1,561 +1,561 @@
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 { 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 } = $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 { currentColumn, dragCol, scrollXLoad, scrollYLoad, overflowX, mergeHeadFlag, tableColumn } = tableReactData
68
- const { fullColumnIdData, scrollXStore, mergeHeaderList, mergeHeaderCellMaps } = tableInternalData
69
- const virtualXOpts = computeVirtualXOpts.value
70
- const columnOpts = computeColumnOpts.value
71
- const columnDragOpts = computeColumnDragOpts.value
72
- const cellOpts = computeCellOpts.value
73
- const defaultRowHeight = computeDefaultRowHeight.value
74
- const headerCellOpts = computeHeaderCellOpts.value
75
- const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
76
- const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = columnDragOpts
77
- const isLastRow = $rowIndex === headerGroups.length - 1
78
-
79
- return cols.map((column, $columnIndex) => {
80
- const { type, showHeaderOverflow, headerAlign, align, filters, headerClassName, editRender, cellRender } = column
81
- const colid = column.id
82
- const colRest = fullColumnIdData[colid] || {}
83
- const renderOpts = editRender || cellRender
84
- const compConf = renderOpts ? renderer.get(renderOpts.name) : null
85
- const isColGroup = column.children && column.children.length
86
- const fixedHiddenColumn = overflowX && !isColGroup && (fixedType ? column.fixed !== fixedType : !!column.fixed)
87
- const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
88
- const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
89
- const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
90
- const showEllipsis = headOverflow === 'ellipsis'
91
- const showTitle = headOverflow === 'title'
92
- const showTooltip = headOverflow === true || headOverflow === 'tooltip'
93
- const hasEllipsis = showTitle || showTooltip || showEllipsis
94
- let hasFilter = false
95
- let firstFilterOption: VxeTableDefines.FilterOption | null = null
96
- if (filters) {
97
- firstFilterOption = filters[0] as VxeTableDefines.FilterOption
98
- hasFilter = filters.some((item) => item.checked)
99
- }
100
- const columnIndex = colRest.index
101
- const _columnIndex = colRest._index
102
- const cellParams: VxeTableDefines.CellRenderHeaderParams & {
103
- $table: VxeTableConstructor & VxeTablePrivateMethods
104
- } = {
105
- $table: $xeTable,
106
- $grid: $xeGrid,
107
- $gantt: $xeGantt,
108
- $rowIndex,
109
- column,
110
- columnIndex,
111
- $columnIndex,
112
- _columnIndex,
113
- firstFilterOption: firstFilterOption as VxeTableDefines.FilterOption,
114
- fixed: fixedType,
115
- source: sourceType,
116
- type: renderType,
117
- isHidden: fixedHiddenColumn,
118
- hasFilter
119
- }
120
- const thAttrs: Record<string, string | number | null> = {
121
- colid
122
- }
123
- let isMergeCell = false
124
- // 合并行或列
125
- if (!showCustomHeader) {
126
- thAttrs.colspan = column.colSpan > 1 ? column.colSpan : null
127
- thAttrs.rowspan = column.rowSpan > 1 ? column.rowSpan : null
128
- }
129
- if (mergeHeadFlag && mergeHeaderList.length && (showCustomHeader || isLastRow)) {
130
- const spanRest = mergeHeaderCellMaps[`${$rowIndex}:${showCustomHeader ? $columnIndex : _columnIndex}`]
131
- if (spanRest) {
132
- const { rowspan, colspan } = spanRest
133
- if (!rowspan || !colspan) {
134
- return null
135
- }
136
- if (rowspan > 1) {
137
- isMergeCell = true
138
- thAttrs.rowspan = rowspan
139
- }
140
- if (colspan > 1) {
141
- isMergeCell = true
142
- thAttrs.colspan = colspan
143
- }
144
- }
145
- }
146
-
147
- const thOns: any = {
148
- onClick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellClickEvent(evnt, cellParams),
149
- onDblclick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellDblclickEvent(evnt, cellParams)
150
- }
151
- const isColDragCell = columnOpts.drag && columnDragOpts.trigger === 'cell'
152
- let isDisabledDrag = false
153
- if (isColDragCell) {
154
- isDisabledDrag = !!(dragDisabledMethod && dragDisabledMethod(cellParams))
155
- }
156
- // 按下事件处理
157
- if (mouseConfig || isColDragCell) {
158
- thOns.onMousedown = (evnt: MouseEvent) => $xeTable.triggerHeaderCellMousedownEvent(evnt, cellParams)
159
- }
160
- // 拖拽列事件
161
- if (columnOpts.drag) {
162
- thOns.onDragstart = $xeTable.handleHeaderCellDragDragstartEvent
163
- thOns.onDragend = $xeTable.handleHeaderCellDragDragendEvent
164
- thOns.onDragover = $xeTable.handleHeaderCellDragDragoverEvent
165
- if (isColDragCell) {
166
- thOns.onMouseup = $xeTable.handleHeaderCellDragMouseupEvent
167
- }
168
- }
169
- const isLastColumn = $columnIndex === cols.length - 1
170
- const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
171
- const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
172
-
173
- let isVNPreEmptyStatus = false
174
- if (isOptimizeMode && overflowX && !isGroup && !isMergeCell) {
175
- if (!dragCol || dragCol.id !== colid) {
176
- if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
177
- isVNPreEmptyStatus = true
178
- }
179
- }
180
- }
181
-
182
- const tcStyle: Record<string, string> = {}
183
- if (hasEllipsis) {
184
- tcStyle.height = `${currCellHeight}px`
185
- } else {
186
- tcStyle.minHeight = `${currCellHeight}px`
187
- }
188
-
189
- if (showCustomHeader) {
190
- // custom
191
- } else if (isColGroup && !isLastRow) {
192
- let childWidth = 0
193
- XEUtils.eachTree(column.children, (childRow) => {
194
- if (childRow.visible && (!childRow.children || !childRow.children.length)) {
195
- childWidth += childRow.renderWidth
196
- }
197
- })
198
- tcStyle.width = `${childWidth}px`
199
- }
200
-
201
- return h('th', {
202
- class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
203
- [`col--${headAlign}`]: headAlign,
204
- [`col--${type}`]: type,
205
- 'col--last': isLastColumn,
206
- 'col--fixed': column.fixed,
207
- 'col--group': isColGroup,
208
- 'col--ellipsis': hasEllipsis,
209
- 'fixed--width': !isAutoCellWidth,
210
- 'is--padding': isPadding,
211
- 'is--sortable': column.sortable,
212
- 'col--filter': !!filters,
213
- 'is--filter-active': hasFilter,
214
- 'is--drag-active': columnOpts.drag && !column.fixed && !isDisabledDrag && (isCrossDrag || isPeerDrag || !column.parentId),
215
- 'is--drag-disabled': columnOpts.drag && isDisabledDrag,
216
- 'col--current': currentColumn === column
217
- },
218
- headerClassName ? (XEUtils.isFunction(headerClassName) ? headerClassName(cellParams) : headerClassName) : '',
219
- headerCellClassName ? (XEUtils.isFunction(headerCellClassName) ? headerCellClassName(cellParams) : headerCellClassName) : ''
220
- ],
221
- style: headerCellStyle ? (XEUtils.isFunction(headerCellStyle) ? headerCellStyle(cellParams) : headerCellStyle) : null,
222
- ...thAttrs,
223
- ...thOns,
224
- key: showCustomHeader ? `${colid}${$columnIndex}` : (columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex)
225
- }, [
226
- h('div', {
227
- class: ['vxe-cell', {
228
- 'c--title': showTitle,
229
- 'c--tooltip': showTooltip,
230
- 'c--ellipsis': showEllipsis
231
- }],
232
- style: tcStyle
233
- }, isVNPreEmptyStatus || (isOptimizeMode && fixedHiddenColumn)
234
- ? []
235
- : [
236
- h('div', {
237
- colid,
238
- class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
239
- }, column.renderHeader(cellParams))
240
- ]),
241
- /**
242
- * 列宽拖动
243
- */
244
- !fixedHiddenColumn && showResizable && (!showCustomHeader || isLastRow)
245
- ? h('div', {
246
- class: 'vxe-cell--col-resizable',
247
- onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
248
- onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
249
- })
250
- : renderEmptyElement($xeTable)
251
- ])
252
- })
253
- }
254
-
255
- const renderFilterRows = (isOptimizeMode: boolean, cols: VxeTableDefines.ColumnInfo[]) => {
256
- const $xeGrid = $xeTable.xeGrid
257
- const $xeGantt = $xeTable.xeGantt
258
-
259
- const { fixedType } = props
260
- const { showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign } = tableProps
261
- const { currentColumn, overflowX } = tableReactData
262
- const { fullColumnIdData } = tableInternalData
263
- const cellOpts = computeCellOpts.value
264
- const defaultRowHeight = computeDefaultRowHeight.value
265
- const headerCellOpts = computeHeaderCellOpts.value
266
- const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
267
-
268
- return cols.map((column, $columnIndex) => {
269
- const { type, showHeaderOverflow, headerAlign, align, filters, editRender, cellRender, floatingFilters, filterRender, slots } = column
270
- const colid = column.id
271
- const colRest = fullColumnIdData[colid] || {}
272
- const renderOpts = editRender || cellRender
273
- const flSlot = slots ? (slots.floatingFilter || slots['floating-filter']) : null
274
- const compConf = renderOpts ? renderer.get(renderOpts.name) : null
275
- const flCompConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null
276
- const rtFloatingFilter = flCompConf ? flCompConf.renderTableFloatingFilter : null
277
- const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
278
- const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
279
- const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
280
- const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
281
- const showEllipsis = headOverflow === 'ellipsis'
282
- const showTitle = headOverflow === 'title'
283
- const showTooltip = headOverflow === true || headOverflow === 'tooltip'
284
- const hasEllipsis = showTitle || showTooltip || showEllipsis
285
- let hasFilter = false
286
- let firstFilterOption: VxeTableDefines.FilterOption | null = null
287
- if (filters) {
288
- firstFilterOption = filters[0] as VxeTableDefines.FilterOption
289
- hasFilter = filters.some((item) => item.checked)
290
- }
291
- const columnIndex = colRest.index
292
- const _columnIndex = colRest._index
293
- const cellParams: VxeTableDefines.CellFloatingFilterParams & {
294
- $table: VxeTableConstructor & VxeTablePrivateMethods
295
- } = {
296
- $table: $xeTable,
297
- $grid: $xeGrid,
298
- $gantt: $xeGantt,
299
- column,
300
- columnIndex,
301
- $columnIndex,
302
- _columnIndex,
303
- option: firstFilterOption as VxeTableDefines.FilterOption,
304
- fixed: fixedType,
305
- source: sourceType,
306
- type: renderType,
307
- isHidden: fixedHiddenColumn,
308
- hasFilter
309
- }
310
- const thAttrs: Record<string, string | number | null> = {
311
- colid
312
- }
313
-
314
- const isLastColumn = $columnIndex === cols.length - 1
315
- const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
316
-
317
- const tcStyle: Record<string, string> = {}
318
- if (hasEllipsis) {
319
- tcStyle.height = `${currCellHeight}px`
320
- } else {
321
- tcStyle.minHeight = `${currCellHeight}px`
322
- }
323
-
324
- return h('th', {
325
- class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
326
- [`col--${headAlign}`]: headAlign,
327
- [`col--${type}`]: type,
328
- 'col--last': isLastColumn,
329
- 'col--fixed': column.fixed,
330
- 'col--ellipsis': hasEllipsis,
331
- 'fixed--width': !isAutoCellWidth,
332
- 'is--padding': isPadding,
333
- 'is--sortable': column.sortable,
334
- 'col--current': currentColumn === column
335
- }
336
- ],
337
- key: colid,
338
- ...thAttrs
339
- }, [
340
- h('div', {
341
- class: ['vxe-cell', {
342
- 'c--title': showTitle,
343
- 'c--tooltip': showTooltip,
344
- 'c--ellipsis': showEllipsis
345
- }],
346
- style: tcStyle
347
- }, isOptimizeMode && fixedHiddenColumn && !floatingFilters
348
- ? []
349
- : [
350
- h('div', {
351
- colid,
352
- class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
353
- }, flSlot
354
- ? $xeTable.callSlot(flSlot, cellParams)
355
- : (rtFloatingFilter && firstFilterOption
356
- ? getSlotVNs(rtFloatingFilter(filterRender, cellParams as unknown as VxeGlobalRendererHandles.RenderTableFloatingFilterParams))
357
- : []))
358
- ])
359
- ])
360
- })
361
- }
362
-
363
- const renderHeads = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], renderColumnList: VxeTableDefines.ColumnInfo[]) => {
364
- const { fixedType } = props
365
-
366
- const { headerRowClassName, headerRowStyle } = tableProps
367
- const floatingFilterOpts = computeFloatingFilterOpts.value
368
- const rowVNs = headerGroups.map((cols, $rowIndex) => {
369
- const params = { $table: $xeTable, $rowIndex, fixed: fixedType, type: renderType }
370
- return h('tr', {
371
- key: $rowIndex,
372
- class: [
373
- 'vxe-header--row',
374
- headerRowClassName ? (XEUtils.isFunction(headerRowClassName) ? headerRowClassName(params) : headerRowClassName) : ''
375
- ],
376
- style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) : null
377
- }, renderRows(isGroup, isOptimizeMode, headerGroups, $rowIndex, cols))
378
- })
379
-
380
- if (floatingFilterOpts.enabled) {
381
- rowVNs.push(
382
- h('tr', {
383
- key: 'ff',
384
- class: [
385
- 'vxe-header--row'
386
- ]
387
- }, renderFilterRows(isOptimizeMode, renderColumnList))
388
- )
389
- }
390
-
391
- return rowVNs
392
- }
393
-
394
- const renderVN = () => {
395
- const { fixedType, fixedColumn, tableColumn } = props
396
- const { mouseConfig } = tableProps
397
- const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
398
- const { visibleColumn, fullColumnIdData } = tableInternalData
399
-
400
- const mouseOpts = computeMouseOpts.value
401
- const isHeaderRenderOptimize = computeIsHeaderRenderOptimize.value
402
- let renderHeaderList = headerColumn.value || []
403
- let renderColumnList = tableColumn as VxeTableDefines.ColumnInfo[]
404
- const isOptimizeMode = isHeaderRenderOptimize
405
-
406
- if (isGroup) {
407
- renderColumnList = visibleColumn
408
- } else {
409
- if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
410
- renderColumnList = visibleColumn
411
- }
412
-
413
- if (fixedType) {
414
- // 如果是使用优化模式
415
- if (isOptimizeMode) {
416
- renderColumnList = fixedColumn || []
417
- }
418
- }
419
- renderHeaderList = [renderColumnList]
420
- }
421
-
422
- if (!fixedType && !isGroup) {
423
- // 列拖拽
424
- if (scrollXLoad && dragCol) {
425
- if (renderColumnList.length > 2) {
426
- const dCowRest = fullColumnIdData[dragCol.id]
427
- if (dCowRest) {
428
- const dcIndex = dCowRest._index
429
- const firstCol = renderColumnList[0]
430
- const lastCol = renderColumnList[renderColumnList.length - 1]
431
- const firstColRest = fullColumnIdData[firstCol.id]
432
- const lastColRest = fullColumnIdData[lastCol.id]
433
- if (firstColRest && lastColRest) {
434
- const fcIndex = firstColRest._index
435
- const lcIndex = lastColRest._index
436
- if (dcIndex < fcIndex) {
437
- renderColumnList = [dragCol].concat(renderColumnList)
438
- renderHeaderList = [[dragCol].concat(renderHeaderList[0])].concat(renderHeaderList.slice(1))
439
- } else if (dcIndex > lcIndex) {
440
- renderColumnList = renderColumnList.concat([dragCol])
441
- renderHeaderList = [renderHeaderList[0].concat([dragCol])].concat(renderHeaderList.slice(1))
442
- }
443
- }
444
- }
445
- }
446
- }
447
- }
448
-
449
- return h('div', {
450
- ref: refElem,
451
- class: ['vxe-table--header-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
452
- xid: xID
453
- }, [
454
- h('div', {
455
- ref: refHeaderScroll,
456
- class: 'vxe-table--header-inner-wrapper',
457
- onScroll (evnt) {
458
- $xeTable.triggerHeaderScrollEvent(evnt, fixedType)
459
- }
460
- }, [
461
- fixedType
462
- ? renderEmptyElement($xeTable)
463
- : h('div', {
464
- ref: refHeaderXSpace,
465
- class: 'vxe-body--x-space'
466
- }),
467
- h('table', {
468
- ref: refHeaderTable,
469
- class: 'vxe-table--header',
470
- xid: xID,
471
- cellspacing: 0,
472
- cellpadding: 0,
473
- border: 0,
474
- xvm: isOptimizeMode ? '1' : null
475
- }, [
476
- /**
477
- * 列宽
478
- */
479
- h('colgroup', {
480
- ref: refHeaderColgroup
481
- }, renderColumnList.map((column, $columnIndex) => {
482
- return h('col', {
483
- name: column.id,
484
- key: $columnIndex,
485
- style: {
486
- width: `${column.renderWidth}px`
487
- }
488
- })
489
- })),
490
- /**
491
- * 头部
492
- */
493
- h('thead', {
494
- ref: refHeaderTHead
495
- }, renderHeads(isGroup, isOptimizeMode, renderHeaderList, renderColumnList))
496
- ]),
497
- mouseConfig && mouseOpts.area
498
- ? h('div', {
499
- class: 'vxe-table--cell-area',
500
- xid: xID
501
- }, [
502
- h('span', {
503
- class: 'vxe-table--cell-main-area'
504
- }),
505
- h('span', {
506
- class: 'vxe-table--cell-clip-area'
507
- }),
508
- h('span', {
509
- class: 'vxe-table--cell-extend-area'
510
- }),
511
- h('span', {
512
- class: 'vxe-table--cell-multi-area'
513
- }),
514
- h('span', {
515
- class: 'vxe-table--cell-active-area'
516
- }),
517
- h('span', {
518
- class: 'vxe-table--cell-col-status-area'
519
- })
520
- ])
521
- : renderEmptyElement($xeTable)
522
- ])
523
- ])
524
- }
525
-
526
- watch(() => props.tableColumn, uploadColumn)
527
-
528
- onMounted(() => {
529
- nextTick(() => {
530
- const { fixedType } = props
531
- const { internalData } = $xeTable
532
- const { elemStore } = internalData
533
- const prefix = `${fixedType || 'main'}-header-`
534
- elemStore[`${prefix}wrapper`] = refElem
535
- elemStore[`${prefix}scroll`] = refHeaderScroll
536
- elemStore[`${prefix}table`] = refHeaderTable
537
- elemStore[`${prefix}colgroup`] = refHeaderColgroup
538
- elemStore[`${prefix}list`] = refHeaderTHead
539
- elemStore[`${prefix}xSpace`] = refHeaderXSpace
540
- elemStore[`${prefix}repair`] = refHeaderBorderRepair
541
- uploadColumn()
542
- })
543
- })
544
-
545
- onUnmounted(() => {
546
- const { fixedType } = props
547
- const { internalData } = $xeTable
548
- const { elemStore } = internalData
549
- const prefix = `${fixedType || 'main'}-header-`
550
- elemStore[`${prefix}wrapper`] = null
551
- elemStore[`${prefix}scroll`] = null
552
- elemStore[`${prefix}table`] = null
553
- elemStore[`${prefix}colgroup`] = null
554
- elemStore[`${prefix}list`] = null
555
- elemStore[`${prefix}xSpace`] = null
556
- elemStore[`${prefix}repair`] = null
557
- })
558
-
559
- return renderVN
560
- }
561
- })
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 { 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 } = $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 { currentColumn, dragCol, scrollXLoad, scrollYLoad, overflowX, mergeHeadFlag, tableColumn } = tableReactData
68
+ const { fullColumnIdData, scrollXStore, mergeHeaderList, mergeHeaderCellMaps } = tableInternalData
69
+ const virtualXOpts = computeVirtualXOpts.value
70
+ const columnOpts = computeColumnOpts.value
71
+ const columnDragOpts = computeColumnDragOpts.value
72
+ const cellOpts = computeCellOpts.value
73
+ const defaultRowHeight = computeDefaultRowHeight.value
74
+ const headerCellOpts = computeHeaderCellOpts.value
75
+ const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
76
+ const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = columnDragOpts
77
+ const isLastRow = $rowIndex === headerGroups.length - 1
78
+
79
+ return cols.map((column, $columnIndex) => {
80
+ const { type, showHeaderOverflow, headerAlign, align, filters, headerClassName, editRender, cellRender } = column
81
+ const colid = column.id
82
+ const colRest = fullColumnIdData[colid] || {}
83
+ const renderOpts = editRender || cellRender
84
+ const compConf = renderOpts ? renderer.get(renderOpts.name) : null
85
+ const isColGroup = column.children && column.children.length
86
+ const fixedHiddenColumn = overflowX && !isColGroup && (fixedType ? column.fixed !== fixedType : !!column.fixed)
87
+ const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
88
+ const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
89
+ const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
90
+ const showEllipsis = headOverflow === 'ellipsis'
91
+ const showTitle = headOverflow === 'title'
92
+ const showTooltip = headOverflow === true || headOverflow === 'tooltip'
93
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
94
+ let hasFilter = false
95
+ let firstFilterOption: VxeTableDefines.FilterOption | null = null
96
+ if (filters) {
97
+ firstFilterOption = filters[0] as VxeTableDefines.FilterOption
98
+ hasFilter = filters.some((item) => item.checked)
99
+ }
100
+ const columnIndex = colRest.index
101
+ const _columnIndex = colRest._index
102
+ const cellParams: VxeTableDefines.CellRenderHeaderParams & {
103
+ $table: VxeTableConstructor & VxeTablePrivateMethods
104
+ } = {
105
+ $table: $xeTable,
106
+ $grid: $xeGrid,
107
+ $gantt: $xeGantt,
108
+ $rowIndex,
109
+ column,
110
+ columnIndex,
111
+ $columnIndex,
112
+ _columnIndex,
113
+ firstFilterOption: firstFilterOption as VxeTableDefines.FilterOption,
114
+ fixed: fixedType,
115
+ source: sourceType,
116
+ type: renderType,
117
+ isHidden: fixedHiddenColumn,
118
+ hasFilter
119
+ }
120
+ const thAttrs: Record<string, string | number | null> = {
121
+ colid
122
+ }
123
+ let isMergeCell = false
124
+ // 合并行或列
125
+ if (!showCustomHeader) {
126
+ thAttrs.colspan = column.colSpan > 1 ? column.colSpan : null
127
+ thAttrs.rowspan = column.rowSpan > 1 ? column.rowSpan : null
128
+ }
129
+ if (mergeHeadFlag && mergeHeaderList.length && (showCustomHeader || isLastRow)) {
130
+ const spanRest = mergeHeaderCellMaps[`${$rowIndex}:${showCustomHeader ? $columnIndex : _columnIndex}`]
131
+ if (spanRest) {
132
+ const { rowspan, colspan } = spanRest
133
+ if (!rowspan || !colspan) {
134
+ return null
135
+ }
136
+ if (rowspan > 1) {
137
+ isMergeCell = true
138
+ thAttrs.rowspan = rowspan
139
+ }
140
+ if (colspan > 1) {
141
+ isMergeCell = true
142
+ thAttrs.colspan = colspan
143
+ }
144
+ }
145
+ }
146
+
147
+ const thOns: any = {
148
+ onClick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellClickEvent(evnt, cellParams),
149
+ onDblclick: (evnt: MouseEvent) => $xeTable.triggerHeaderCellDblclickEvent(evnt, cellParams)
150
+ }
151
+ const isColDragCell = columnOpts.drag && columnDragOpts.trigger === 'cell'
152
+ let isDisabledDrag = false
153
+ if (isColDragCell) {
154
+ isDisabledDrag = !!(dragDisabledMethod && dragDisabledMethod(cellParams))
155
+ }
156
+ // 按下事件处理
157
+ if (mouseConfig || isColDragCell) {
158
+ thOns.onMousedown = (evnt: MouseEvent) => $xeTable.triggerHeaderCellMousedownEvent(evnt, cellParams)
159
+ }
160
+ // 拖拽列事件
161
+ if (columnOpts.drag) {
162
+ thOns.onDragstart = $xeTable.handleHeaderCellDragDragstartEvent
163
+ thOns.onDragend = $xeTable.handleHeaderCellDragDragendEvent
164
+ thOns.onDragover = $xeTable.handleHeaderCellDragDragoverEvent
165
+ if (isColDragCell) {
166
+ thOns.onMouseup = $xeTable.handleHeaderCellDragMouseupEvent
167
+ }
168
+ }
169
+ const isLastColumn = $columnIndex === cols.length - 1
170
+ const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
171
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
172
+
173
+ let isVNPreEmptyStatus = false
174
+ if (isOptimizeMode && overflowX && !isGroup && !isMergeCell) {
175
+ if (!dragCol || dragCol.id !== colid) {
176
+ if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
177
+ isVNPreEmptyStatus = true
178
+ }
179
+ }
180
+ }
181
+
182
+ const tcStyle: Record<string, string> = {}
183
+ if (hasEllipsis) {
184
+ tcStyle.height = `${currCellHeight}px`
185
+ } else {
186
+ tcStyle.minHeight = `${currCellHeight}px`
187
+ }
188
+
189
+ if (showCustomHeader) {
190
+ // custom
191
+ } else if (isColGroup && !isLastRow) {
192
+ let childWidth = 0
193
+ XEUtils.eachTree(column.children, (childRow) => {
194
+ if (childRow.visible && (!childRow.children || !childRow.children.length)) {
195
+ childWidth += childRow.renderWidth
196
+ }
197
+ })
198
+ tcStyle.width = `${childWidth}px`
199
+ }
200
+
201
+ return h('th', {
202
+ class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
203
+ [`col--${headAlign}`]: headAlign,
204
+ [`col--${type}`]: type,
205
+ 'col--last': isLastColumn,
206
+ 'col--fixed': column.fixed,
207
+ 'col--group': isColGroup,
208
+ 'col--ellipsis': hasEllipsis,
209
+ 'fixed--width': !isAutoCellWidth,
210
+ 'is--padding': isPadding,
211
+ 'is--sortable': column.sortable,
212
+ 'col--filter': !!filters,
213
+ 'is--filter-active': hasFilter,
214
+ 'is--drag-active': columnOpts.drag && !column.fixed && !isDisabledDrag && (isCrossDrag || isPeerDrag || !column.parentId),
215
+ 'is--drag-disabled': columnOpts.drag && isDisabledDrag,
216
+ 'col--current': currentColumn === column
217
+ },
218
+ headerClassName ? (XEUtils.isFunction(headerClassName) ? headerClassName(cellParams) : headerClassName) : '',
219
+ headerCellClassName ? (XEUtils.isFunction(headerCellClassName) ? headerCellClassName(cellParams) : headerCellClassName) : ''
220
+ ],
221
+ style: headerCellStyle ? (XEUtils.isFunction(headerCellStyle) ? headerCellStyle(cellParams) : headerCellStyle) : null,
222
+ ...thAttrs,
223
+ ...thOns,
224
+ key: showCustomHeader ? `${colid}${$columnIndex}` : (columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex)
225
+ }, [
226
+ h('div', {
227
+ class: ['vxe-cell', {
228
+ 'c--title': showTitle,
229
+ 'c--tooltip': showTooltip,
230
+ 'c--ellipsis': showEllipsis
231
+ }],
232
+ style: tcStyle
233
+ }, isVNPreEmptyStatus || (isOptimizeMode && fixedHiddenColumn)
234
+ ? []
235
+ : [
236
+ h('div', {
237
+ colid,
238
+ class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
239
+ }, column.renderHeader(cellParams))
240
+ ]),
241
+ /**
242
+ * 列宽拖动
243
+ */
244
+ !fixedHiddenColumn && showResizable && (!showCustomHeader || isLastRow)
245
+ ? h('div', {
246
+ class: 'vxe-cell--col-resizable',
247
+ onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
248
+ onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
249
+ })
250
+ : renderEmptyElement($xeTable)
251
+ ])
252
+ })
253
+ }
254
+
255
+ const renderFilterRows = (isOptimizeMode: boolean, cols: VxeTableDefines.ColumnInfo[]) => {
256
+ const $xeGrid = $xeTable.xeGrid
257
+ const $xeGantt = $xeTable.xeGantt
258
+
259
+ const { fixedType } = props
260
+ const { showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign } = tableProps
261
+ const { currentColumn, overflowX } = tableReactData
262
+ const { fullColumnIdData } = tableInternalData
263
+ const cellOpts = computeCellOpts.value
264
+ const defaultRowHeight = computeDefaultRowHeight.value
265
+ const headerCellOpts = computeHeaderCellOpts.value
266
+ const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
267
+
268
+ return cols.map((column, $columnIndex) => {
269
+ const { type, showHeaderOverflow, headerAlign, align, filters, editRender, cellRender, floatingFilters, filterRender, slots } = column
270
+ const colid = column.id
271
+ const colRest = fullColumnIdData[colid] || {}
272
+ const renderOpts = editRender || cellRender
273
+ const flSlot = slots ? (slots.floatingFilter || slots['floating-filter']) : null
274
+ const compConf = renderOpts ? renderer.get(renderOpts.name) : null
275
+ const flCompConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null
276
+ const rtFloatingFilter = flCompConf ? flCompConf.renderTableFloatingFilter : null
277
+ const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
278
+ const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
279
+ const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
280
+ const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
281
+ const showEllipsis = headOverflow === 'ellipsis'
282
+ const showTitle = headOverflow === 'title'
283
+ const showTooltip = headOverflow === true || headOverflow === 'tooltip'
284
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
285
+ let hasFilter = false
286
+ let firstFilterOption: VxeTableDefines.FilterOption | null = null
287
+ if (filters) {
288
+ firstFilterOption = filters[0] as VxeTableDefines.FilterOption
289
+ hasFilter = filters.some((item) => item.checked)
290
+ }
291
+ const columnIndex = colRest.index
292
+ const _columnIndex = colRest._index
293
+ const cellParams: VxeTableDefines.CellFloatingFilterParams & {
294
+ $table: VxeTableConstructor & VxeTablePrivateMethods
295
+ } = {
296
+ $table: $xeTable,
297
+ $grid: $xeGrid,
298
+ $gantt: $xeGantt,
299
+ column,
300
+ columnIndex,
301
+ $columnIndex,
302
+ _columnIndex,
303
+ option: firstFilterOption as VxeTableDefines.FilterOption,
304
+ fixed: fixedType,
305
+ source: sourceType,
306
+ type: renderType,
307
+ isHidden: fixedHiddenColumn,
308
+ hasFilter
309
+ }
310
+ const thAttrs: Record<string, string | number | null> = {
311
+ colid
312
+ }
313
+
314
+ const isLastColumn = $columnIndex === cols.length - 1
315
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
316
+
317
+ const tcStyle: Record<string, string> = {}
318
+ if (hasEllipsis) {
319
+ tcStyle.height = `${currCellHeight}px`
320
+ } else {
321
+ tcStyle.minHeight = `${currCellHeight}px`
322
+ }
323
+
324
+ return h('th', {
325
+ class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
326
+ [`col--${headAlign}`]: headAlign,
327
+ [`col--${type}`]: type,
328
+ 'col--last': isLastColumn,
329
+ 'col--fixed': column.fixed,
330
+ 'col--ellipsis': hasEllipsis,
331
+ 'fixed--width': !isAutoCellWidth,
332
+ 'is--padding': isPadding,
333
+ 'is--sortable': column.sortable,
334
+ 'col--current': currentColumn === column
335
+ }
336
+ ],
337
+ key: colid,
338
+ ...thAttrs
339
+ }, [
340
+ h('div', {
341
+ class: ['vxe-cell', {
342
+ 'c--title': showTitle,
343
+ 'c--tooltip': showTooltip,
344
+ 'c--ellipsis': showEllipsis
345
+ }],
346
+ style: tcStyle
347
+ }, isOptimizeMode && fixedHiddenColumn && !floatingFilters
348
+ ? []
349
+ : [
350
+ h('div', {
351
+ colid,
352
+ class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
353
+ }, flSlot
354
+ ? $xeTable.callSlot(flSlot, cellParams)
355
+ : (rtFloatingFilter && firstFilterOption
356
+ ? getSlotVNs(rtFloatingFilter(filterRender, cellParams as unknown as VxeGlobalRendererHandles.RenderTableFloatingFilterParams))
357
+ : []))
358
+ ])
359
+ ])
360
+ })
361
+ }
362
+
363
+ const renderHeads = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], renderColumnList: VxeTableDefines.ColumnInfo[]) => {
364
+ const { fixedType } = props
365
+
366
+ const { headerRowClassName, headerRowStyle } = tableProps
367
+ const floatingFilterOpts = computeFloatingFilterOpts.value
368
+ const rowVNs = headerGroups.map((cols, $rowIndex) => {
369
+ const params = { $table: $xeTable, $rowIndex, fixed: fixedType, type: renderType }
370
+ return h('tr', {
371
+ key: $rowIndex,
372
+ class: [
373
+ 'vxe-header--row',
374
+ headerRowClassName ? (XEUtils.isFunction(headerRowClassName) ? headerRowClassName(params) : headerRowClassName) : ''
375
+ ],
376
+ style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) : null
377
+ }, renderRows(isGroup, isOptimizeMode, headerGroups, $rowIndex, cols))
378
+ })
379
+
380
+ if (floatingFilterOpts.enabled) {
381
+ rowVNs.push(
382
+ h('tr', {
383
+ key: 'ff',
384
+ class: [
385
+ 'vxe-header--row'
386
+ ]
387
+ }, renderFilterRows(isOptimizeMode, renderColumnList))
388
+ )
389
+ }
390
+
391
+ return rowVNs
392
+ }
393
+
394
+ const renderVN = () => {
395
+ const { fixedType, fixedColumn, tableColumn } = props
396
+ const { mouseConfig } = tableProps
397
+ const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
398
+ const { visibleColumn, fullColumnIdData } = tableInternalData
399
+
400
+ const mouseOpts = computeMouseOpts.value
401
+ const isHeaderRenderOptimize = computeIsHeaderRenderOptimize.value
402
+ let renderHeaderList = headerColumn.value || []
403
+ let renderColumnList = tableColumn as VxeTableDefines.ColumnInfo[]
404
+ const isOptimizeMode = isHeaderRenderOptimize
405
+
406
+ if (isGroup) {
407
+ renderColumnList = visibleColumn
408
+ } else {
409
+ if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
410
+ renderColumnList = visibleColumn
411
+ }
412
+
413
+ if (fixedType) {
414
+ // 如果是使用优化模式
415
+ if (isOptimizeMode) {
416
+ renderColumnList = fixedColumn || []
417
+ }
418
+ }
419
+ renderHeaderList = [renderColumnList]
420
+ }
421
+
422
+ if (!fixedType && !isGroup) {
423
+ // 列拖拽
424
+ if (scrollXLoad && dragCol) {
425
+ if (renderColumnList.length > 2) {
426
+ const dCowRest = fullColumnIdData[dragCol.id]
427
+ if (dCowRest) {
428
+ const dcIndex = dCowRest._index
429
+ const firstCol = renderColumnList[0]
430
+ const lastCol = renderColumnList[renderColumnList.length - 1]
431
+ const firstColRest = fullColumnIdData[firstCol.id]
432
+ const lastColRest = fullColumnIdData[lastCol.id]
433
+ if (firstColRest && lastColRest) {
434
+ const fcIndex = firstColRest._index
435
+ const lcIndex = lastColRest._index
436
+ if (dcIndex < fcIndex) {
437
+ renderColumnList = [dragCol].concat(renderColumnList)
438
+ renderHeaderList = [[dragCol].concat(renderHeaderList[0])].concat(renderHeaderList.slice(1))
439
+ } else if (dcIndex > lcIndex) {
440
+ renderColumnList = renderColumnList.concat([dragCol])
441
+ renderHeaderList = [renderHeaderList[0].concat([dragCol])].concat(renderHeaderList.slice(1))
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+ return h('div', {
450
+ ref: refElem,
451
+ class: ['vxe-table--header-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
452
+ xid: xID
453
+ }, [
454
+ h('div', {
455
+ ref: refHeaderScroll,
456
+ class: 'vxe-table--header-inner-wrapper',
457
+ onScroll (evnt) {
458
+ $xeTable.triggerHeaderScrollEvent(evnt, fixedType)
459
+ }
460
+ }, [
461
+ fixedType
462
+ ? renderEmptyElement($xeTable)
463
+ : h('div', {
464
+ ref: refHeaderXSpace,
465
+ class: 'vxe-body--x-space'
466
+ }),
467
+ h('table', {
468
+ ref: refHeaderTable,
469
+ class: 'vxe-table--header',
470
+ xid: xID,
471
+ cellspacing: 0,
472
+ cellpadding: 0,
473
+ border: 0,
474
+ xvm: isOptimizeMode ? '1' : null
475
+ }, [
476
+ /**
477
+ * 列宽
478
+ */
479
+ h('colgroup', {
480
+ ref: refHeaderColgroup
481
+ }, renderColumnList.map((column, $columnIndex) => {
482
+ return h('col', {
483
+ name: column.id,
484
+ key: $columnIndex,
485
+ style: {
486
+ width: `${column.renderWidth}px`
487
+ }
488
+ })
489
+ })),
490
+ /**
491
+ * 头部
492
+ */
493
+ h('thead', {
494
+ ref: refHeaderTHead
495
+ }, renderHeads(isGroup, isOptimizeMode, renderHeaderList, renderColumnList))
496
+ ]),
497
+ mouseConfig && mouseOpts.area
498
+ ? h('div', {
499
+ class: 'vxe-table--cell-area',
500
+ xid: xID
501
+ }, [
502
+ h('span', {
503
+ class: 'vxe-table--cell-main-area'
504
+ }),
505
+ h('span', {
506
+ class: 'vxe-table--cell-clip-area'
507
+ }),
508
+ h('span', {
509
+ class: 'vxe-table--cell-extend-area'
510
+ }),
511
+ h('span', {
512
+ class: 'vxe-table--cell-multi-area'
513
+ }),
514
+ h('span', {
515
+ class: 'vxe-table--cell-active-area'
516
+ }),
517
+ h('span', {
518
+ class: 'vxe-table--cell-col-status-area'
519
+ })
520
+ ])
521
+ : renderEmptyElement($xeTable)
522
+ ])
523
+ ])
524
+ }
525
+
526
+ watch(() => props.tableColumn, uploadColumn)
527
+
528
+ onMounted(() => {
529
+ nextTick(() => {
530
+ const { fixedType } = props
531
+ const { internalData } = $xeTable
532
+ const { elemStore } = internalData
533
+ const prefix = `${fixedType || 'main'}-header-`
534
+ elemStore[`${prefix}wrapper`] = refElem
535
+ elemStore[`${prefix}scroll`] = refHeaderScroll
536
+ elemStore[`${prefix}table`] = refHeaderTable
537
+ elemStore[`${prefix}colgroup`] = refHeaderColgroup
538
+ elemStore[`${prefix}list`] = refHeaderTHead
539
+ elemStore[`${prefix}xSpace`] = refHeaderXSpace
540
+ elemStore[`${prefix}repair`] = refHeaderBorderRepair
541
+ uploadColumn()
542
+ })
543
+ })
544
+
545
+ onUnmounted(() => {
546
+ const { fixedType } = props
547
+ const { internalData } = $xeTable
548
+ const { elemStore } = internalData
549
+ const prefix = `${fixedType || 'main'}-header-`
550
+ elemStore[`${prefix}wrapper`] = null
551
+ elemStore[`${prefix}scroll`] = null
552
+ elemStore[`${prefix}table`] = null
553
+ elemStore[`${prefix}colgroup`] = null
554
+ elemStore[`${prefix}list`] = null
555
+ elemStore[`${prefix}xSpace`] = null
556
+ elemStore[`${prefix}repair`] = null
557
+ })
558
+
559
+ return renderVN
560
+ }
561
+ })