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,380 +1,425 @@
1
- import { h, ref, Ref, PropType, inject, nextTick, onMounted, onUnmounted } from 'vue'
2
- import { defineVxeComponent } from '../../ui/src/comp'
3
- import XEUtils from 'xe-utils'
4
- import { VxeUI } from '../../ui'
5
- import { updateCellTitle, getPropClass } from '../../ui/src/dom'
6
- import { getCalcHeight } from './util'
7
-
8
- import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines } from '../../../types'
9
- import { getDefaultConfig } from '../../ui/src/utils'
10
-
11
- const { renderer, renderEmptyElement } = VxeUI
12
-
13
- const sourceType = 'table'
14
- const renderType = 'footer'
15
-
16
- export default defineVxeComponent({
17
- name: 'VxeTableFooter',
18
- props: {
19
- footerTableData: {
20
- type: Array as PropType<any[][]>,
21
- default: () => []
22
- },
23
- tableColumn: {
24
- type: Array as PropType<VxeTableDefines.ColumnInfo[]>,
25
- default: () => []
26
- },
27
- fixedColumn: {
28
- type: Array as PropType<VxeTableDefines.ColumnInfo[]>,
29
- default: () => []
30
- },
31
- fixedType: {
32
- type: String as PropType<'right' | 'left' | ''>,
33
- default: null
34
- }
35
- },
36
- setup (props) {
37
- const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)
38
-
39
- const { xID, props: tableProps, reactData: tableReactData, internalData: tableInternalData } = $xeTable
40
- const { computeFooterTooltipOpts, computeColumnOpts, computeCellOpts, computeFooterCellOpts, computeDefaultRowHeight, computeResizableOpts, computeVirtualXOpts, computeIsFooterRenderOptimize, computeRendererOpts } = $xeTable.getComputeMaps()
41
-
42
- const refElem = ref() as Ref<HTMLDivElement>
43
- const refFooterScroll = ref() as Ref<HTMLDivElement>
44
- const refFooterTable = ref() as Ref<HTMLTableElement>
45
- const refFooterColgroup = ref() as Ref<HTMLTableColElement>
46
- const refFooterTFoot = ref() as Ref<HTMLTableSectionElement>
47
- const refFooterXSpace = ref() as Ref<HTMLDivElement>
48
-
49
- const renderRows = (isOptimizeMode: boolean, tableColumn: VxeTableDefines.ColumnInfo[], footerTableData: any[], row: any, $rowIndex: number, _rowIndex: number) => {
50
- const $xeGrid = $xeTable.xeGrid
51
- const $xeGantt = $xeTable.xeGantt
52
-
53
- const { fixedType } = props
54
- const { resizable: allResizable, border, footerCellClassName, footerCellStyle, footerAlign: allFooterAlign, footerSpanMethod, align: allAlign, columnKey, showFooterOverflow: allColumnFooterOverflow } = tableProps
55
- const { scrollXLoad, scrollYLoad, overflowX, mergeFootFlag, currColFlag } = tableReactData
56
- const { fullColumnIdData, mergeFooterList, mergeFooterCellMaps, scrollXStore, currentCol } = tableInternalData
57
- const virtualXOpts = computeVirtualXOpts.value
58
- const footerTooltipOpts = computeFooterTooltipOpts.value
59
- const resizableOpts = computeResizableOpts.value
60
- const { isAllColumnDrag } = resizableOpts
61
- const columnOpts = computeColumnOpts.value
62
- const defaultRowHeight = computeDefaultRowHeight.value
63
- const cellOpts = computeCellOpts.value
64
- const footerCellOpts = computeFooterCellOpts.value
65
- const currCellHeight = getCalcHeight(footerCellOpts.height) || defaultRowHeight
66
- const rendererOpts = computeRendererOpts.value
67
-
68
- return tableColumn.map((column, $columnIndex) => {
69
- const { type, showFooterOverflow, footerAlign, align, footerClassName, editRender, cellRender } = column
70
- const colid = column.id
71
- const colRest = fullColumnIdData[colid] || {}
72
- const renderOpts = editRender || cellRender
73
- const compConf = renderOpts && renderOpts.name ? (rendererOpts[renderOpts.name] || renderer.get(renderOpts.name)) : null
74
- const showAllTip = footerTooltipOpts.showAll
75
- const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
76
-
77
- const cellPadding = getDefaultConfig(footerCellOpts.padding, cellOpts.padding)
78
- const isAllCellPadding = cellPadding === true
79
- const isCellPaddingTop = cellPadding ? (isAllCellPadding || cellPadding.top !== false) : false
80
- const isCellPaddingBottom = cellPadding ? (isAllCellPadding || cellPadding.bottom !== false) : false
81
- const isCellPaddingLeft = cellPadding ? (isAllCellPadding || cellPadding.left !== false) : false
82
- const isCellPaddingRight = cellPadding ? (isAllCellPadding || cellPadding.right !== false) : false
83
-
84
- const footOverflow = getDefaultConfig(showFooterOverflow, allColumnFooterOverflow)
85
- const footAlign = footerAlign || (compConf ? compConf.tableFooterCellAlign : '') || allFooterAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
86
- const showEllipsis = (footOverflow === true ? footerTooltipOpts.mode : footOverflow) === 'ellipsis'
87
- const showTitle = (footOverflow === true ? footerTooltipOpts.mode : footOverflow) === 'title'
88
- const showTooltip = (footOverflow === true ? footerTooltipOpts.mode : footOverflow) === 'tooltip'
89
- const hasEllipsis = showTitle || showTooltip || showEllipsis
90
- const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable))
91
- const attrs: any = { colid }
92
- const tfOns: any = {}
93
- const columnIndex = colRest.index
94
- const _columnIndex = colRest._index
95
- const itemIndex = _columnIndex
96
- const cellParams: VxeTableDefines.CellRenderFooterParams & {
97
- $table: VxeTableConstructor<any> & VxeTablePrivateMethods
98
- } = {
99
- $table: $xeTable,
100
- $grid: $xeGrid,
101
- $gantt: $xeGantt,
102
- row,
103
- rowIndex: _rowIndex,
104
- _rowIndex,
105
- $rowIndex,
106
- column,
107
- columnIndex,
108
- $columnIndex,
109
- _columnIndex,
110
- itemIndex,
111
- items: row,
112
- fixed: fixedType,
113
- source: sourceType,
114
- type: renderType,
115
- data: footerTableData
116
- }
117
- if (showTitle || showTooltip || showAllTip) {
118
- tfOns.onMouseenter = (evnt: MouseEvent) => {
119
- if (showTitle) {
120
- updateCellTitle(evnt.currentTarget, column)
121
- } else if (showTooltip || showAllTip) {
122
- $xeTable.triggerFooterTooltipEvent(evnt, cellParams)
123
- }
124
- }
125
- }
126
- if (showTooltip || showAllTip) {
127
- tfOns.onMouseleave = (evnt: MouseEvent) => {
128
- if (showTooltip || showAllTip) {
129
- $xeTable.handleTargetLeaveEvent(evnt)
130
- }
131
- }
132
- }
133
- tfOns.onClick = (evnt: MouseEvent) => {
134
- $xeTable.triggerFooterCellClickEvent(evnt, cellParams)
135
- }
136
- tfOns.onDblclick = (evnt: MouseEvent) => {
137
- $xeTable.triggerFooterCellDblclickEvent(evnt, cellParams)
138
- }
139
- let isMergeCell = false
140
- // 合并行或列
141
- if (mergeFootFlag && mergeFooterList.length) {
142
- const spanRest = mergeFooterCellMaps[`${_rowIndex}:${_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
- attrs.rowspan = rowspan
151
- }
152
- if (colspan > 1) {
153
- isMergeCell = true
154
- attrs.colspan = colspan
155
- }
156
- }
157
- } else if (footerSpanMethod) {
158
- // 自定义合并方法
159
- const { rowspan = 1, colspan = 1 } = footerSpanMethod(cellParams) || {}
160
- if (!rowspan || !colspan) {
161
- return null
162
- }
163
- if (rowspan > 1) {
164
- attrs.rowspan = rowspan
165
- }
166
- if (colspan > 1) {
167
- attrs.colspan = colspan
168
- }
169
- }
170
- const isLastColumn = $columnIndex === tableColumn.length - 1
171
- const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
172
-
173
- let isVNPreEmptyStatus = false
174
- if (isOptimizeMode && overflowX && !isMergeCell) {
175
- if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
176
- isVNPreEmptyStatus = true
177
- }
178
- }
179
-
180
- const tcStyle: Record<string, string> = {}
181
- if (hasEllipsis) {
182
- tcStyle.height = `${currCellHeight}px`
183
- } else {
184
- tcStyle.minHeight = `${currCellHeight}px`
185
- }
186
-
187
- return h('td', {
188
- class: ['vxe-table--column vxe-footer--column', column.id, {
189
- [`col--${footAlign}`]: footAlign,
190
- [`col--${type}`]: type,
191
- 'col--last': isLastColumn,
192
- 'fixed--width': !isAutoCellWidth,
193
- 'fixed--hidden': fixedHiddenColumn,
194
- 'is--pg-top': isCellPaddingTop,
195
- 'is--pg-bottom': isCellPaddingBottom,
196
- 'is--pg-left': isCellPaddingLeft,
197
- 'is--pg-right': isCellPaddingRight,
198
- 'col--ellipsis': hasEllipsis,
199
- 'col--current': currColFlag && currentCol === column
200
- }, getPropClass(footerClassName, cellParams), getPropClass(footerCellClassName, cellParams)],
201
- ...attrs,
202
- style: footerCellStyle ? (XEUtils.isFunction(footerCellStyle) ? footerCellStyle(cellParams) : footerCellStyle) : null,
203
- ...tfOns,
204
- key: columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag ? column.id : $columnIndex
205
- }, [
206
- h('div', {
207
- class: ['vxe-cell', {
208
- 'c--title': showTitle,
209
- 'c--tooltip': showTooltip,
210
- 'c--ellipsis': showEllipsis
211
- }],
212
- style: tcStyle
213
- }, isVNPreEmptyStatus
214
- ? []
215
- : [
216
- h('div', {
217
- colid,
218
- class: 'vxe-cell--wrapper vxe-footer-cell--wrapper'
219
- }, column.renderFooter(cellParams))
220
- ]),
221
- /**
222
- * 列宽拖动
223
- */
224
- !fixedHiddenColumn && showResizable && isAllColumnDrag
225
- ? h('div', {
226
- class: ['vxe-cell--col-resizable', {
227
- 'is--line': !border || border === 'none'
228
- }],
229
- onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
230
- onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
231
- })
232
- : renderEmptyElement($xeTable)
233
- ])
234
- })
235
- }
236
-
237
- const renderHeads = (isOptimizeMode: boolean, renderColumnList: VxeTableDefines.ColumnInfo[]) => {
238
- const { fixedType, footerTableData } = props
239
- const { footerRowClassName, footerRowStyle } = tableProps
240
-
241
- return footerTableData.map((row, _rowIndex) => {
242
- const $rowIndex = _rowIndex
243
- const rowParams = { $table: $xeTable, row, rowIndex: _rowIndex, _rowIndex, $rowIndex, fixed: fixedType, type: renderType }
244
-
245
- return h('tr', {
246
- key: _rowIndex,
247
- class: [
248
- 'vxe-footer--row',
249
- footerRowClassName ? XEUtils.isFunction(footerRowClassName) ? footerRowClassName(rowParams) : footerRowClassName : ''
250
- ],
251
- style: footerRowStyle ? (XEUtils.isFunction(footerRowStyle) ? footerRowStyle(rowParams) : footerRowStyle) : null
252
- }, renderRows(isOptimizeMode, renderColumnList, footerTableData, row, _rowIndex, _rowIndex))
253
- })
254
- }
255
-
256
- const renderVN = () => {
257
- const { fixedType, fixedColumn, tableColumn } = props
258
- const { visibleColumn, fullColumnIdData } = tableInternalData
259
- const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
260
- const isFooterRenderOptimize = computeIsFooterRenderOptimize.value
261
-
262
- let renderColumnList = tableColumn
263
- const isOptimizeMode = isFooterRenderOptimize
264
-
265
- if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
266
- renderColumnList = visibleColumn
267
- }
268
-
269
- if (fixedType) {
270
- if (isOptimizeMode) {
271
- renderColumnList = fixedColumn || []
272
- }
273
- }
274
-
275
- if (!fixedType && !isGroup) {
276
- // 列拖拽
277
- if (scrollXLoad && dragCol) {
278
- if (renderColumnList.length > 2) {
279
- const dCowRest = fullColumnIdData[dragCol.id]
280
- if (dCowRest) {
281
- const dcIndex = dCowRest._index
282
- const firstCol = renderColumnList[0]
283
- const lastCol = renderColumnList[renderColumnList.length - 1]
284
- const firstColRest = fullColumnIdData[firstCol.id]
285
- const lastColRest = fullColumnIdData[lastCol.id]
286
- if (firstColRest && lastColRest) {
287
- const fcIndex = firstColRest._index
288
- const lcIndex = lastColRest._index
289
- if (dcIndex < fcIndex) {
290
- renderColumnList = [dragCol].concat(renderColumnList)
291
- } else if (dcIndex > lcIndex) {
292
- renderColumnList = renderColumnList.concat([dragCol])
293
- }
294
- }
295
- }
296
- }
297
- }
298
- }
299
-
300
- return h('div', {
301
- ref: refElem,
302
- class: ['vxe-table--footer-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
303
- xid: xID
304
- }, [
305
- h('div', {
306
- ref: refFooterScroll,
307
- class: 'vxe-table--footer-inner-wrapper',
308
- onScroll (evnt) {
309
- $xeTable.triggerFooterScrollEvent(evnt, fixedType)
310
- }
311
- }, [
312
- fixedType
313
- ? renderEmptyElement($xeTable)
314
- : h('div', {
315
- ref: refFooterXSpace,
316
- class: 'vxe-body--x-space'
317
- }),
318
- h('table', {
319
- ref: refFooterTable,
320
- class: 'vxe-table--footer',
321
- xid: xID,
322
- cellspacing: 0,
323
- cellpadding: 0,
324
- border: 0,
325
- xvm: isOptimizeMode ? '1' : null
326
- }, [
327
- /**
328
- * 列宽
329
- */
330
- h('colgroup', {
331
- ref: refFooterColgroup
332
- }, renderColumnList.map((column, $columnIndex) => {
333
- return h('col', {
334
- name: column.id,
335
- key: $columnIndex,
336
- style: {
337
- width: `${column.renderWidth}px`
338
- }
339
- })
340
- })),
341
- /**
342
- * 底部
343
- */
344
- h('tfoot', {
345
- ref: refFooterTFoot
346
- }, renderHeads(isOptimizeMode, renderColumnList))
347
- ])
348
- ])
349
- ])
350
- }
351
-
352
- onMounted(() => {
353
- nextTick(() => {
354
- const { fixedType } = props
355
- const { elemStore } = tableInternalData
356
- const prefix = `${fixedType || 'main'}-footer-`
357
- elemStore[`${prefix}wrapper`] = refElem
358
- elemStore[`${prefix}scroll`] = refFooterScroll
359
- elemStore[`${prefix}table`] = refFooterTable
360
- elemStore[`${prefix}colgroup`] = refFooterColgroup
361
- elemStore[`${prefix}list`] = refFooterTFoot
362
- elemStore[`${prefix}xSpace`] = refFooterXSpace
363
- })
364
- })
365
-
366
- onUnmounted(() => {
367
- const { fixedType } = props
368
- const { elemStore } = tableInternalData
369
- const prefix = `${fixedType || 'main'}-footer-`
370
- elemStore[`${prefix}wrapper`] = null
371
- elemStore[`${prefix}scroll`] = null
372
- elemStore[`${prefix}table`] = null
373
- elemStore[`${prefix}colgroup`] = null
374
- elemStore[`${prefix}list`] = null
375
- elemStore[`${prefix}xSpace`] = null
376
- })
377
-
378
- return renderVN
379
- }
380
- })
1
+ import { h, ref, Ref, PropType, inject, nextTick, onMounted, onUnmounted } from 'vue'
2
+ import { defineVxeComponent } from '../../ui/src/comp'
3
+ import XEUtils from 'xe-utils'
4
+ import { VxeUI } from '@vxe-ui/core'
5
+ import { updateCellTitle, getPropClass } from '../../ui/src/dom'
6
+ import { getCalcHeight } from './util'
7
+
8
+ import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines } from '../../../types'
9
+ import { getDefaultConfig } from '../../ui/src/utils'
10
+
11
+ const { renderer, renderEmptyElement } = VxeUI
12
+
13
+ const sourceType = 'table'
14
+ const renderType = 'footer'
15
+
16
+ export default defineVxeComponent({
17
+ name: 'VxeTableFooter',
18
+ props: {
19
+ footerTableData: {
20
+ type: Array as PropType<any[][]>,
21
+ default: () => []
22
+ },
23
+ tableColumn: {
24
+ type: Array as PropType<VxeTableDefines.ColumnInfo[]>,
25
+ default: () => []
26
+ },
27
+ fixedColumn: {
28
+ type: Array as PropType<VxeTableDefines.ColumnInfo[]>,
29
+ default: () => []
30
+ },
31
+ fixedType: {
32
+ type: String as PropType<'right' | 'left' | ''>,
33
+ default: null
34
+ }
35
+ },
36
+ setup(props) {
37
+ const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)
38
+
39
+ const { xID, props: tableProps, reactData: tableReactData, internalData: tableInternalData } = $xeTable
40
+ const { computeFooterTooltipOpts, computeColumnOpts, computeCellOpts, computeFooterCellOpts, computeDefaultRowHeight, computeResizableOpts, computeVirtualXOpts, computeIsFooterRenderOptimize, computeRendererOpts } = $xeTable.getComputeMaps()
41
+
42
+ const refElem = ref() as Ref<HTMLDivElement>
43
+ const refFooterScroll = ref() as Ref<HTMLDivElement>
44
+ const refFooterTable = ref() as Ref<HTMLTableElement>
45
+ const refFooterColgroup = ref() as Ref<HTMLTableColElement>
46
+ const refFooterTFoot = ref() as Ref<HTMLTableSectionElement>
47
+ const refFooterXSpace = ref() as Ref<HTMLDivElement>
48
+
49
+ const renderRows = (isOptimizeMode: boolean, tableColumn: VxeTableDefines.ColumnInfo[], footerTableData: any[], row: any, $rowIndex: number, _rowIndex: number) => {
50
+ const $xeGrid = $xeTable.xeGrid
51
+ const $xeGantt = $xeTable.xeGantt
52
+
53
+ const { fixedType } = props
54
+ const { resizable: allResizable, border, footerCellClassName, footerCellStyle, footerAlign: allFooterAlign, footerSpanMethod, align: allAlign, columnKey, showFooterOverflow: allColumnFooterOverflow } = tableProps
55
+ const { scrollXLoad, scrollYLoad, overflowX, mergeFootFlag, currColFlag } = tableReactData
56
+ const { fullColumnIdData, mergeFooterList, mergeFooterCellMaps, scrollXStore, currentCol } = tableInternalData
57
+ const virtualXOpts = computeVirtualXOpts.value
58
+ const footerTooltipOpts = computeFooterTooltipOpts.value
59
+ const resizableOpts = computeResizableOpts.value
60
+ const { isAllColumnDrag } = resizableOpts
61
+ const columnOpts = computeColumnOpts.value
62
+ const defaultRowHeight = computeDefaultRowHeight.value
63
+ const cellOpts = computeCellOpts.value
64
+ const footerCellOpts = computeFooterCellOpts.value
65
+ const currCellHeight = getCalcHeight(footerCellOpts.height) || defaultRowHeight
66
+ const rendererOpts = computeRendererOpts.value
67
+
68
+ return tableColumn.map((column, $columnIndex) => {
69
+ const { type, showFooterOverflow, footerAlign, align, footerClassName, editRender, cellRender } = column
70
+ const colid = column.id
71
+ const colRest = fullColumnIdData[colid] || {}
72
+ const renderOpts = editRender || cellRender
73
+ const compConf = renderOpts && renderOpts.name ? rendererOpts[renderOpts.name] || renderer.get(renderOpts.name) : null
74
+ const showAllTip = footerTooltipOpts.showAll
75
+ const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
76
+
77
+ const cellPadding = getDefaultConfig(footerCellOpts.padding, cellOpts.padding)
78
+ const isAllCellPadding = cellPadding === true
79
+ const isCellPaddingTop = cellPadding ? isAllCellPadding || cellPadding.top !== false : false
80
+ const isCellPaddingBottom = cellPadding ? isAllCellPadding || cellPadding.bottom !== false : false
81
+ const isCellPaddingLeft = cellPadding ? isAllCellPadding || cellPadding.left !== false : false
82
+ const isCellPaddingRight = cellPadding ? isAllCellPadding || cellPadding.right !== false : false
83
+
84
+ const footOverflow = getDefaultConfig(showFooterOverflow, allColumnFooterOverflow)
85
+ const footAlign = footerAlign || (compConf ? compConf.tableFooterCellAlign : '') || allFooterAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
86
+ const showEllipsis = (footOverflow === true ? footerTooltipOpts.mode : footOverflow) === 'ellipsis'
87
+ const showTitle = (footOverflow === true ? footerTooltipOpts.mode : footOverflow) === 'title'
88
+ const showTooltip = (footOverflow === true ? footerTooltipOpts.mode : footOverflow) === 'tooltip'
89
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
90
+ const showResizable = XEUtils.isBoolean(column.resizable) ? column.resizable : columnOpts.resizable || allResizable
91
+ const attrs: any = { colid }
92
+ const tfOns: any = {}
93
+ const columnIndex = colRest.index
94
+ const _columnIndex = colRest._index
95
+ const itemIndex = _columnIndex
96
+ const cellParams: VxeTableDefines.CellRenderFooterParams & {
97
+ $table: VxeTableConstructor<any> & VxeTablePrivateMethods
98
+ } = {
99
+ $table: $xeTable,
100
+ $grid: $xeGrid,
101
+ $gantt: $xeGantt,
102
+ row,
103
+ rowIndex: _rowIndex,
104
+ _rowIndex,
105
+ $rowIndex,
106
+ column,
107
+ columnIndex,
108
+ $columnIndex,
109
+ _columnIndex,
110
+ itemIndex,
111
+ items: row,
112
+ fixed: fixedType,
113
+ source: sourceType,
114
+ type: renderType,
115
+ data: footerTableData
116
+ }
117
+ if (showTitle || showTooltip || showAllTip) {
118
+ tfOns.onMouseenter = (evnt: MouseEvent) => {
119
+ if (showTitle) {
120
+ updateCellTitle(evnt.currentTarget, column)
121
+ } else if (showTooltip || showAllTip) {
122
+ $xeTable.triggerFooterTooltipEvent(evnt, cellParams)
123
+ }
124
+ }
125
+ }
126
+ if (showTooltip || showAllTip) {
127
+ tfOns.onMouseleave = (evnt: MouseEvent) => {
128
+ if (showTooltip || showAllTip) {
129
+ $xeTable.handleTargetLeaveEvent(evnt)
130
+ }
131
+ }
132
+ }
133
+ tfOns.onClick = (evnt: MouseEvent) => {
134
+ $xeTable.triggerFooterCellClickEvent(evnt, cellParams)
135
+ }
136
+ tfOns.onDblclick = (evnt: MouseEvent) => {
137
+ $xeTable.triggerFooterCellDblclickEvent(evnt, cellParams)
138
+ }
139
+ let isMergeCell = false
140
+ // 合并行或列
141
+ if (mergeFootFlag && mergeFooterList.length) {
142
+ const spanRest = mergeFooterCellMaps[`${_rowIndex}:${_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
+ attrs.rowspan = rowspan
151
+ }
152
+ if (colspan > 1) {
153
+ isMergeCell = true
154
+ attrs.colspan = colspan
155
+ }
156
+ }
157
+ } else if (footerSpanMethod) {
158
+ // 自定义合并方法
159
+ const { rowspan = 1, colspan = 1 } = footerSpanMethod(cellParams) || {}
160
+ if (!rowspan || !colspan) {
161
+ return null
162
+ }
163
+ if (rowspan > 1) {
164
+ attrs.rowspan = rowspan
165
+ }
166
+ if (colspan > 1) {
167
+ attrs.colspan = colspan
168
+ }
169
+ }
170
+ const isLastColumn = $columnIndex === tableColumn.length - 1
171
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
172
+
173
+ let isVNPreEmptyStatus = false
174
+ if (isOptimizeMode && overflowX && !isMergeCell) {
175
+ if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
176
+ isVNPreEmptyStatus = true
177
+ }
178
+ }
179
+
180
+ const tcStyle: Record<string, string> = {}
181
+ if (hasEllipsis) {
182
+ tcStyle.height = `${currCellHeight}px`
183
+ } else {
184
+ tcStyle.minHeight = `${currCellHeight}px`
185
+ }
186
+
187
+ return h(
188
+ 'td',
189
+ {
190
+ class: [
191
+ 'vxe-table--column vxe-footer--column',
192
+ column.id,
193
+ {
194
+ [`col--${footAlign}`]: footAlign,
195
+ [`col--${type}`]: type,
196
+ 'col--last': isLastColumn,
197
+ 'fixed--width': !isAutoCellWidth,
198
+ 'fixed--hidden': fixedHiddenColumn,
199
+ 'is--pg-top': isCellPaddingTop,
200
+ 'is--pg-bottom': isCellPaddingBottom,
201
+ 'is--pg-left': isCellPaddingLeft,
202
+ 'is--pg-right': isCellPaddingRight,
203
+ 'col--ellipsis': hasEllipsis,
204
+ 'col--current': currColFlag && currentCol === column
205
+ },
206
+ getPropClass(footerClassName, cellParams),
207
+ getPropClass(footerCellClassName, cellParams)
208
+ ],
209
+ ...attrs,
210
+ style: footerCellStyle ? (XEUtils.isFunction(footerCellStyle) ? footerCellStyle(cellParams) : footerCellStyle) : null,
211
+ ...tfOns,
212
+ key: columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag ? column.id : $columnIndex
213
+ },
214
+ [
215
+ h(
216
+ 'div',
217
+ {
218
+ class: [
219
+ 'vxe-cell',
220
+ {
221
+ 'c--title': showTitle,
222
+ 'c--tooltip': showTooltip,
223
+ 'c--ellipsis': showEllipsis
224
+ }
225
+ ],
226
+ style: tcStyle
227
+ },
228
+ isVNPreEmptyStatus
229
+ ? []
230
+ : [
231
+ h(
232
+ 'div',
233
+ {
234
+ colid,
235
+ class: 'vxe-cell--wrapper vxe-footer-cell--wrapper'
236
+ },
237
+ column.renderFooter(cellParams)
238
+ )
239
+ ]
240
+ ),
241
+ /**
242
+ * 列宽拖动
243
+ */
244
+ !fixedHiddenColumn && showResizable && isAllColumnDrag
245
+ ? h('div', {
246
+ class: [
247
+ 'vxe-cell--col-resizable',
248
+ {
249
+ 'is--line': !border || border === 'none'
250
+ }
251
+ ],
252
+ onMousedown: (evnt: MouseEvent) => $xeTable.handleColResizeMousedownEvent(evnt, fixedType, cellParams),
253
+ onDblclick: (evnt: MouseEvent) => $xeTable.handleColResizeDblclickEvent(evnt, cellParams)
254
+ })
255
+ : renderEmptyElement($xeTable)
256
+ ]
257
+ )
258
+ })
259
+ }
260
+
261
+ const renderHeads = (isOptimizeMode: boolean, renderColumnList: VxeTableDefines.ColumnInfo[]) => {
262
+ const { fixedType, footerTableData } = props
263
+ const { footerRowClassName, footerRowStyle } = tableProps
264
+
265
+ return footerTableData.map((row, _rowIndex) => {
266
+ const $rowIndex = _rowIndex
267
+ const rowParams = { $table: $xeTable, row, rowIndex: _rowIndex, _rowIndex, $rowIndex, fixed: fixedType, type: renderType }
268
+
269
+ return h(
270
+ 'tr',
271
+ {
272
+ key: _rowIndex,
273
+ class: ['vxe-footer--row', footerRowClassName ? (XEUtils.isFunction(footerRowClassName) ? footerRowClassName(rowParams) : footerRowClassName) : ''],
274
+ style: footerRowStyle ? (XEUtils.isFunction(footerRowStyle) ? footerRowStyle(rowParams) : footerRowStyle) : null
275
+ },
276
+ renderRows(isOptimizeMode, renderColumnList, footerTableData, row, _rowIndex, _rowIndex)
277
+ )
278
+ })
279
+ }
280
+
281
+ const renderVN = () => {
282
+ const { fixedType, fixedColumn, tableColumn } = props
283
+ const { visibleColumn, fullColumnIdData } = tableInternalData
284
+ const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
285
+ const isFooterRenderOptimize = computeIsFooterRenderOptimize.value
286
+
287
+ let renderColumnList = tableColumn
288
+ const isOptimizeMode = isFooterRenderOptimize
289
+
290
+ if (!isOptimizeMode || (!isColLoading && (fixedType || !overflowX))) {
291
+ renderColumnList = visibleColumn
292
+ }
293
+
294
+ if (fixedType) {
295
+ if (isOptimizeMode) {
296
+ renderColumnList = fixedColumn || []
297
+ }
298
+ }
299
+
300
+ if (!fixedType && !isGroup) {
301
+ // 列拖拽
302
+ if (scrollXLoad && dragCol) {
303
+ if (renderColumnList.length > 2) {
304
+ const dCowRest = fullColumnIdData[dragCol.id]
305
+ if (dCowRest) {
306
+ const dcIndex = dCowRest._index
307
+ const firstCol = renderColumnList[0]
308
+ const lastCol = renderColumnList[renderColumnList.length - 1]
309
+ const firstColRest = fullColumnIdData[firstCol.id]
310
+ const lastColRest = fullColumnIdData[lastCol.id]
311
+ if (firstColRest && lastColRest) {
312
+ const fcIndex = firstColRest._index
313
+ const lcIndex = lastColRest._index
314
+ if (dcIndex < fcIndex) {
315
+ renderColumnList = [dragCol].concat(renderColumnList)
316
+ } else if (dcIndex > lcIndex) {
317
+ renderColumnList = renderColumnList.concat([dragCol])
318
+ }
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+
325
+ return h(
326
+ 'div',
327
+ {
328
+ ref: refElem,
329
+ class: ['vxe-table--footer-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
330
+ xid: xID
331
+ },
332
+ [
333
+ h(
334
+ 'div',
335
+ {
336
+ ref: refFooterScroll,
337
+ class: 'vxe-table--footer-inner-wrapper',
338
+ onScroll(evnt) {
339
+ $xeTable.triggerFooterScrollEvent(evnt, fixedType)
340
+ }
341
+ },
342
+ [
343
+ fixedType
344
+ ? renderEmptyElement($xeTable)
345
+ : h('div', {
346
+ ref: refFooterXSpace,
347
+ class: 'vxe-body--x-space'
348
+ }),
349
+ h(
350
+ 'table',
351
+ {
352
+ ref: refFooterTable,
353
+ class: 'vxe-table--footer',
354
+ xid: xID,
355
+ cellspacing: 0,
356
+ cellpadding: 0,
357
+ border: 0,
358
+ xvm: isOptimizeMode ? '1' : null
359
+ },
360
+ [
361
+ /**
362
+ * 列宽
363
+ */
364
+ h(
365
+ 'colgroup',
366
+ {
367
+ ref: refFooterColgroup
368
+ },
369
+ renderColumnList.map((column, $columnIndex) => {
370
+ return h('col', {
371
+ name: column.id,
372
+ key: $columnIndex,
373
+ style: {
374
+ width: `${column.renderWidth}px`
375
+ }
376
+ })
377
+ })
378
+ ),
379
+ /**
380
+ * 底部
381
+ */
382
+ h(
383
+ 'tfoot',
384
+ {
385
+ ref: refFooterTFoot
386
+ },
387
+ renderHeads(isOptimizeMode, renderColumnList)
388
+ )
389
+ ]
390
+ )
391
+ ]
392
+ )
393
+ ]
394
+ )
395
+ }
396
+
397
+ onMounted(() => {
398
+ nextTick(() => {
399
+ const { fixedType } = props
400
+ const { elemStore } = tableInternalData
401
+ const prefix = `${fixedType || 'main'}-footer-`
402
+ elemStore[`${prefix}wrapper`] = refElem
403
+ elemStore[`${prefix}scroll`] = refFooterScroll
404
+ elemStore[`${prefix}table`] = refFooterTable
405
+ elemStore[`${prefix}colgroup`] = refFooterColgroup
406
+ elemStore[`${prefix}list`] = refFooterTFoot
407
+ elemStore[`${prefix}xSpace`] = refFooterXSpace
408
+ })
409
+ })
410
+
411
+ onUnmounted(() => {
412
+ const { fixedType } = props
413
+ const { elemStore } = tableInternalData
414
+ const prefix = `${fixedType || 'main'}-footer-`
415
+ elemStore[`${prefix}wrapper`] = null
416
+ elemStore[`${prefix}scroll`] = null
417
+ elemStore[`${prefix}table`] = null
418
+ elemStore[`${prefix}colgroup`] = null
419
+ elemStore[`${prefix}list`] = null
420
+ elemStore[`${prefix}xSpace`] = null
421
+ })
422
+
423
+ return renderVN
424
+ }
425
+ })