vxe-table 4.23.8 → 4.23.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/all.esm.js +5715 -3783
  2. package/es/components.d.ts +1 -0
  3. package/es/components.js +2 -7
  4. package/es/grid/src/emits.js +1 -15
  5. package/es/grid/src/grid.js +397 -120
  6. package/es/index.esm.js +1 -0
  7. package/es/index.js +1 -0
  8. package/es/table/module/custom/hook.js +49 -42
  9. package/es/table/module/custom/panel.js +777 -527
  10. package/es/table/module/edit/hook.js +140 -62
  11. package/es/table/module/export/export-panel.js +399 -316
  12. package/es/table/module/export/hook.js +395 -337
  13. package/es/table/module/export/import-panel.js +152 -123
  14. package/es/table/module/filter/hook.js +16 -2
  15. package/es/table/module/filter/panel.js +146 -84
  16. package/es/table/module/keyboard/hook.js +8 -4
  17. package/es/table/module/menu/panel.js +197 -126
  18. package/es/table/render/index.js +151 -98
  19. package/es/table/src/body.js +355 -233
  20. package/es/table/src/cell.js +426 -269
  21. package/es/table/src/columnInfo.js +1 -0
  22. package/es/table/src/footer.js +144 -99
  23. package/es/table/src/group.js +7 -3
  24. package/es/table/src/header.js +229 -172
  25. package/es/table/src/table.js +1503 -1030
  26. package/es/table/src/util.js +15 -19
  27. package/es/toolbar/src/toolbar.js +132 -75
  28. package/es/ui/index.js +1 -1
  29. package/es/ui/src/dom.js +9 -6
  30. package/es/ui/src/log.js +1 -1
  31. package/es/ui/src/utils.d.ts +1 -1
  32. package/lib/components.js +2 -7
  33. package/lib/grid/src/emits.js +1 -15
  34. package/lib/grid/src/grid.js +397 -120
  35. package/lib/index.common.js +1 -0
  36. package/lib/index.js +1 -0
  37. package/lib/index.umd.js +5732 -3800
  38. package/lib/index.umd.min.js +3 -3
  39. package/lib/table/module/custom/hook.js +49 -42
  40. package/lib/table/module/custom/panel.js +777 -527
  41. package/lib/table/module/edit/hook.js +140 -62
  42. package/lib/table/module/export/export-panel.js +399 -316
  43. package/lib/table/module/export/hook.js +395 -337
  44. package/lib/table/module/export/import-panel.js +152 -123
  45. package/lib/table/module/filter/hook.js +16 -2
  46. package/lib/table/module/filter/panel.js +146 -84
  47. package/lib/table/module/keyboard/hook.js +8 -4
  48. package/lib/table/module/menu/panel.js +197 -126
  49. package/lib/table/render/index.js +151 -98
  50. package/lib/table/src/body.js +355 -233
  51. package/lib/table/src/cell.js +426 -269
  52. package/lib/table/src/columnInfo.js +1 -0
  53. package/lib/table/src/footer.js +144 -99
  54. package/lib/table/src/group.js +7 -3
  55. package/lib/table/src/header.js +229 -172
  56. package/lib/table/src/table.js +1471 -1029
  57. package/lib/table/src/util.js +15 -19
  58. package/lib/toolbar/src/toolbar.js +132 -75
  59. package/lib/ui/index.js +1 -1
  60. package/lib/ui/src/dom.js +9 -6
  61. package/lib/ui/src/log.js +1 -1
  62. package/package.json +2 -2
  63. package/packages/colgroup/index.ts +22 -22
  64. package/packages/column/index.ts +22 -22
  65. package/packages/components.ts +41 -44
  66. package/packages/grid/index.ts +18 -18
  67. package/packages/grid/src/emits.ts +5 -19
  68. package/packages/grid/src/grid.ts +2229 -1925
  69. package/packages/grid/src/props.ts +22 -23
  70. package/packages/index.ts +11 -11
  71. package/packages/locale/lang/fr-FR.ts +15 -15
  72. package/packages/locale/lang/it-IT.ts +4 -4
  73. package/packages/locale/lang/uk-UA.ts +1 -1
  74. package/packages/locale/lang/uz-UZ.ts +13 -13
  75. package/packages/locale/lang/zh-CN.ts +907 -907
  76. package/packages/table/index.ts +26 -26
  77. package/packages/table/module/custom/hook.ts +510 -503
  78. package/packages/table/module/custom/panel.ts +2002 -1743
  79. package/packages/table/module/edit/hook.ts +1224 -1131
  80. package/packages/table/module/export/export-panel.ts +697 -611
  81. package/packages/table/module/export/hook.ts +2160 -2059
  82. package/packages/table/module/export/import-panel.ts +319 -279
  83. package/packages/table/module/export/util.ts +25 -24
  84. package/packages/table/module/filter/hook.ts +519 -501
  85. package/packages/table/module/filter/panel.ts +368 -304
  86. package/packages/table/module/keyboard/hook.ts +498 -494
  87. package/packages/table/module/menu/hook.ts +330 -330
  88. package/packages/table/module/menu/panel.ts +272 -201
  89. package/packages/table/module/validator/hook.ts +653 -635
  90. package/packages/table/render/index.ts +1819 -1744
  91. package/packages/table/src/body.ts +1078 -955
  92. package/packages/table/src/cell.ts +1524 -1359
  93. package/packages/table/src/column.ts +192 -192
  94. package/packages/table/src/columnInfo.ts +232 -232
  95. package/packages/table/src/emits.ts +134 -134
  96. package/packages/table/src/footer.ts +425 -380
  97. package/packages/table/src/group.ts +67 -63
  98. package/packages/table/src/header.ts +642 -581
  99. package/packages/table/src/props.ts +336 -336
  100. package/packages/table/src/store.ts +14 -14
  101. package/packages/table/src/table.ts +16011 -15454
  102. package/packages/table/src/use/cell-view.ts +41 -44
  103. package/packages/table/src/use/index.ts +1 -1
  104. package/packages/table/src/util.ts +1206 -1216
  105. package/packages/toolbar/index.ts +18 -18
  106. package/packages/toolbar/src/toolbar.ts +768 -706
  107. package/packages/ui/index.ts +519 -520
  108. package/packages/ui/src/anime.ts +51 -52
  109. package/packages/ui/src/comp.ts +3 -3
  110. package/packages/ui/src/dom.ts +466 -463
  111. package/packages/ui/src/log.ts +19 -19
  112. package/packages/ui/src/utils.ts +66 -66
  113. package/packages/ui/src/vn.ts +55 -55
  114. package/packages/v-x-e-table/index.d.ts +3 -3
  115. package/packages/v-x-e-table/index.ts +3 -3
  116. package/types/all.d.ts +76 -76
  117. package/types/index.d.ts +4 -4
  118. /package/dist/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  119. /package/dist/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  120. /package/dist/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
  121. /package/es/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  122. /package/es/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  123. /package/es/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
  124. /package/lib/{iconfont.1793007753347.ttf → iconfont.1793009263429.ttf} +0 -0
  125. /package/lib/{iconfont.1793007753347.woff → iconfont.1793009263429.woff} +0 -0
  126. /package/lib/{iconfont.1793007753347.woff2 → iconfont.1793009263429.woff2} +0 -0
@@ -1,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 '@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('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
+ })