vxe-table 3.18.0 → 3.18.2

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 (83) hide show
  1. package/es/index.css +1 -1
  2. package/es/index.min.css +1 -1
  3. package/es/style.css +1 -1
  4. package/es/style.min.css +1 -1
  5. package/es/table/module/edit/mixin.js +58 -20
  6. package/es/table/module/filter/mixin.js +12 -10
  7. package/es/table/module/menu/mixin.js +16 -9
  8. package/es/table/module/validator/mixin.js +4 -2
  9. package/es/table/src/column.js +2 -0
  10. package/es/table/src/columnInfo.js +1 -0
  11. package/es/table/src/footer.js +7 -5
  12. package/es/table/src/header.js +67 -28
  13. package/es/table/src/methods.js +577 -85
  14. package/es/table/src/props.js +23 -6
  15. package/es/table/src/store.js +8 -0
  16. package/es/table/src/table.js +67 -26
  17. package/es/table/src/util.js +70 -2
  18. package/es/table/style.css +11 -17
  19. package/es/table/style.min.css +1 -1
  20. package/es/ui/index.js +1 -1
  21. package/es/ui/src/log.js +1 -1
  22. package/es/vxe-table/style.css +11 -17
  23. package/es/vxe-table/style.min.css +1 -1
  24. package/lib/index.css +1 -1
  25. package/lib/index.min.css +1 -1
  26. package/lib/index.umd.js +1002 -200
  27. package/lib/index.umd.min.js +1 -1
  28. package/lib/style.css +1 -1
  29. package/lib/style.min.css +1 -1
  30. package/lib/table/module/edit/mixin.js +55 -16
  31. package/lib/table/module/edit/mixin.min.js +1 -1
  32. package/lib/table/module/filter/mixin.js +12 -10
  33. package/lib/table/module/filter/mixin.min.js +1 -1
  34. package/lib/table/module/menu/mixin.js +20 -13
  35. package/lib/table/module/menu/mixin.min.js +1 -1
  36. package/lib/table/module/validator/mixin.js +4 -2
  37. package/lib/table/module/validator/mixin.min.js +1 -1
  38. package/lib/table/src/column.js +2 -0
  39. package/lib/table/src/column.min.js +1 -1
  40. package/lib/table/src/columnInfo.js +1 -0
  41. package/lib/table/src/columnInfo.min.js +1 -1
  42. package/lib/table/src/footer.js +7 -5
  43. package/lib/table/src/header.js +82 -25
  44. package/lib/table/src/header.min.js +1 -1
  45. package/lib/table/src/methods.js +647 -94
  46. package/lib/table/src/methods.min.js +1 -1
  47. package/lib/table/src/props.js +11 -3
  48. package/lib/table/src/props.min.js +1 -1
  49. package/lib/table/src/store.js +15 -0
  50. package/lib/table/src/store.min.js +1 -0
  51. package/lib/table/src/table.js +74 -25
  52. package/lib/table/src/table.min.js +1 -1
  53. package/lib/table/src/util.js +74 -2
  54. package/lib/table/src/util.min.js +1 -1
  55. package/lib/table/style/style.css +11 -17
  56. package/lib/table/style/style.min.css +1 -1
  57. package/lib/ui/index.js +1 -1
  58. package/lib/ui/index.min.js +1 -1
  59. package/lib/ui/src/log.js +1 -1
  60. package/lib/ui/src/log.min.js +1 -1
  61. package/lib/vxe-table/style/style.css +11 -17
  62. package/lib/vxe-table/style/style.min.css +1 -1
  63. package/package.json +1 -1
  64. package/packages/table/module/edit/mixin.ts +59 -23
  65. package/packages/table/module/filter/mixin.ts +17 -13
  66. package/packages/table/module/menu/mixin.ts +16 -9
  67. package/packages/table/module/validator/mixin.ts +8 -4
  68. package/packages/table/src/column.ts +4 -2
  69. package/packages/table/src/columnInfo.ts +1 -0
  70. package/packages/table/src/footer.ts +11 -9
  71. package/packages/table/src/header.ts +76 -34
  72. package/packages/table/src/methods.ts +607 -90
  73. package/packages/table/src/props.ts +29 -12
  74. package/packages/table/src/store.ts +15 -0
  75. package/packages/table/src/table.ts +79 -24
  76. package/packages/table/src/util.ts +76 -2
  77. package/styles/components/table.scss +33 -55
  78. /package/es/{iconfont.1756083626568.ttf → iconfont.1756452257212.ttf} +0 -0
  79. /package/es/{iconfont.1756083626568.woff → iconfont.1756452257212.woff} +0 -0
  80. /package/es/{iconfont.1756083626568.woff2 → iconfont.1756452257212.woff2} +0 -0
  81. /package/lib/{iconfont.1756083626568.ttf → iconfont.1756452257212.ttf} +0 -0
  82. /package/lib/{iconfont.1756083626568.woff → iconfont.1756452257212.woff} +0 -0
  83. /package/lib/{iconfont.1756083626568.woff2 → iconfont.1756452257212.woff2} +0 -0
@@ -107,14 +107,18 @@ function handleInsertRowAt ($xeTable: VxeTableConstructor & VxeTablePrivateMetho
107
107
 
108
108
  const { treeConfig } = props
109
109
  const { isRowGroupStatus } = reactData
110
- const { tableFullTreeData, afterFullData, mergeBodyList, tableFullData, fullDataRowIdData, fullAllDataRowIdData, insertRowMaps } = internalData
110
+ const { tableFullTreeData, afterFullData, mergeBodyList, tableFullData, fullDataRowIdData, fullAllDataRowIdData, insertRowMaps, removeRowMaps } = internalData
111
111
  const treeOpts = $xeTable.computeTreeOpts
112
- const { transform, rowField, mapChildrenField } = treeOpts
112
+ const { transform, parentField, rowField, mapChildrenField } = treeOpts
113
113
  const childrenField = treeOpts.children || treeOpts.childrenField
114
114
  if (!XEUtils.isArray(records)) {
115
115
  records = [records]
116
116
  }
117
117
  const newRecords: any[] = $xeTable.defineField(records.map(record => Object.assign(treeConfig && transform ? { [mapChildrenField]: [], [childrenField]: [] } : {}, record)))
118
+ let treeRecords: any[] = []
119
+ if (treeConfig && transform) {
120
+ treeRecords = XEUtils.toArrayTree(newRecords, { key: rowField, parentKey: parentField, children: childrenField })
121
+ }
118
122
  if (XEUtils.eqNull(targetRow)) {
119
123
  // 如果为虚拟树
120
124
  if (treeConfig && transform) {
@@ -168,42 +172,49 @@ function handleInsertRowAt ($xeTable: VxeTableConstructor & VxeTablePrivateMetho
168
172
  } else {
169
173
  // 如果为虚拟树
170
174
  if (treeConfig && transform) {
171
- const matchMapObj = XEUtils.findTree(tableFullTreeData, (item: any) => targetRow[rowField] === item[rowField], { children: mapChildrenField })
175
+ const matchMapObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: mapChildrenField })
172
176
  if (matchMapObj) {
173
- const { parent: parentRow } = matchMapObj as any
177
+ const { parent: parentRow } = matchMapObj
174
178
  const parentMapChilds = parentRow ? parentRow[mapChildrenField] : tableFullTreeData
175
179
  const parentRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)]
176
180
  const parentLevel = parentRest ? parentRest.level : 0
177
- newRecords.forEach((item: any, i: any) => {
178
- const rowid = getRowid($xeTable, item)
179
- if (item[treeOpts.parentField]) {
180
- if (parentRow && item[treeOpts.parentField] !== parentRow[rowField]) {
181
- errLog('vxe.error.errProp', [`${treeOpts.parentField}=${item[treeOpts.parentField]}`, `${treeOpts.parentField}=${parentRow[rowField]}`])
182
- }
183
- }
181
+ treeRecords.forEach((row, i) => {
184
182
  if (parentRow) {
185
- item[treeOpts.parentField] = parentRow[rowField]
183
+ if (row[parentField] !== parentRow[rowField]) {
184
+ row[parentField] = parentRow[rowField]
185
+ errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, `${parentField}=${parentRow[rowField]}`])
186
+ }
187
+ } else {
188
+ if (row[parentField] !== null) {
189
+ row[parentField] = null
190
+ errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, 'null'])
191
+ }
186
192
  }
187
193
  let targetIndex = matchMapObj.index + i
188
194
  if (isInsertNextRow) {
189
195
  targetIndex = targetIndex + 1
190
196
  }
191
- parentMapChilds.splice(targetIndex, 0, item)
197
+ parentMapChilds.splice(targetIndex, 0, row)
198
+ })
199
+ XEUtils.eachTree(treeRecords, (item) => {
200
+ const rowid = getRowid($xeTable, item)
192
201
  const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: parentMapChilds, parent: parentRow, level: parentLevel + 1, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
202
+ if (item[childrenField]) {
203
+ item[mapChildrenField] = item[childrenField]
204
+ }
193
205
  fullDataRowIdData[rowid] = rest
194
206
  fullAllDataRowIdData[rowid] = rest
195
- })
196
-
207
+ }, { children: childrenField })
197
208
  // 源
198
209
  if (parentRow) {
199
- const matchObj = XEUtils.findTree(tableFullTreeData, (item: any) => targetRow[rowField] === item[rowField], { children: childrenField })
210
+ const matchObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: childrenField })
200
211
  if (matchObj) {
201
212
  const parentChilds = matchObj.items
202
213
  let targetIndex = matchObj.index
203
214
  if (isInsertNextRow) {
204
215
  targetIndex = targetIndex + 1
205
216
  }
206
- parentChilds.splice(targetIndex, 0, ...newRecords)
217
+ parentChilds.splice(targetIndex, 0, ...treeRecords)
207
218
  }
208
219
  }
209
220
  } else {
@@ -234,7 +245,7 @@ function handleInsertRowAt ($xeTable: VxeTableConstructor & VxeTablePrivateMetho
234
245
  afIndex = Math.min(afterFullData.length, afIndex + 1)
235
246
  }
236
247
  if (afIndex === -1) {
237
- throw new Error(errLog('vxe.error.unableInsert'))
248
+ throw new Error(getI18n('vxe.error.unableInsert'))
238
249
  }
239
250
  afterFullData.splice(afIndex, 0, ...newRecords)
240
251
  const tfIndex = $xeTable.findRowIndexOf(tableFullData, targetRow)
@@ -255,10 +266,27 @@ function handleInsertRowAt ($xeTable: VxeTableConstructor & VxeTablePrivateMetho
255
266
  }
256
267
  }
257
268
  }
258
- newRecords.forEach(newRow => {
269
+
270
+ const handleStatus = (newRow: any) => {
259
271
  const rowid = getRowid($xeTable, newRow)
260
- insertRowMaps[rowid] = newRow
261
- })
272
+ // 如果是被删除的数据,则还原状态
273
+ if (removeRowMaps[rowid]) {
274
+ delete removeRowMaps[rowid]
275
+ if (insertRowMaps[rowid]) {
276
+ delete insertRowMaps[rowid]
277
+ }
278
+ } else {
279
+ insertRowMaps[rowid] = newRow
280
+ }
281
+ }
282
+ // 如果为虚拟树
283
+ if (treeConfig && transform) {
284
+ XEUtils.eachTree(treeRecords, handleStatus, { children: mapChildrenField })
285
+ } else {
286
+ newRecords.forEach(handleStatus)
287
+ }
288
+
289
+ reactData.removeRowFlag++
262
290
  reactData.insertRowFlag++
263
291
  $xeTable.cacheRowMap(false)
264
292
  $xeTable.updateScrollYStatus()
@@ -815,7 +843,12 @@ export default {
815
843
  const { editStore } = reactData
816
844
  const { row, column } = editStore.actived
817
845
  if (column && row) {
818
- return { row, column }
846
+ return {
847
+ row,
848
+ rowIndex: $xeTable.getRowIndex(row),
849
+ column,
850
+ columnIndex: $xeTable.getColumnIndex(column)
851
+ }
819
852
  }
820
853
  return null
821
854
  },
@@ -1008,7 +1041,10 @@ export default {
1008
1041
  const { editStore } = reactData
1009
1042
  const { row, column } = editStore.selected
1010
1043
  if (row && column) {
1011
- return { row, column }
1044
+ return {
1045
+ row,
1046
+ column
1047
+ }
1012
1048
  }
1013
1049
  return null
1014
1050
  },
@@ -15,11 +15,13 @@ export default {
15
15
  * @param column
16
16
  */
17
17
  _openFilter (fieldOrColumn: any) {
18
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
19
+
18
20
  const column = handleFieldOrColumn(this, fieldOrColumn)
19
21
  if (column && column.filters) {
20
22
  const { elemStore } = this
21
23
  const { fixed } = column
22
- return this.scrollToColumn(column).then(() => {
24
+ return $xeTable.scrollToColumn(column).then(() => {
23
25
  const headerWrapperElem = elemStore[`${fixed || 'main'}-header-wrapper`] || elemStore['main-header-wrapper']
24
26
  if (headerWrapperElem) {
25
27
  const filterBtnElem = headerWrapperElem.querySelector(`.vxe-header--column.${column.id} .vxe-cell--filter`)
@@ -27,7 +29,7 @@ export default {
27
29
  }
28
30
  })
29
31
  }
30
- return this.$nextTick()
32
+ return $xeTable.$nextTick()
31
33
  },
32
34
  /**
33
35
  * 修改筛选条件列表
@@ -195,9 +197,9 @@ export default {
195
197
  return filterList
196
198
  },
197
199
  handleColumnConfirmFilter (column: VxeTableDefines.ColumnInfo, evnt: Event | null) {
198
- const $xeTable = this
200
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
199
201
  const props = $xeTable
200
- const reactData = $xeTable
202
+ const reactData = $xeTable as unknown as TableReactData
201
203
 
202
204
  const { mouseConfig } = props
203
205
  const { scrollXLoad: oldScrollXLoad, scrollYLoad: oldScrollYLoad } = reactData
@@ -212,22 +214,22 @@ export default {
212
214
  datas.push(item.data)
213
215
  }
214
216
  })
215
- const filterList = this.getCheckedFilters()
216
- const params = { $table: this, $event: evnt, column, field, property: field, values, datas, filters: filterList, filterList }
217
+ const filterList = $xeTable.getCheckedFilters()
218
+ const params = { $table: $xeTable, $event: evnt as Event, column, field, property: field, values, datas, filters: filterList, filterList }
217
219
  // 如果是服务端筛选,则跳过本地筛选处理
218
220
  if (!filterOpts.remote) {
219
- this.handleTableData(true)
220
- this.checkSelectionStatus()
221
+ $xeTable.handleTableData(true)
222
+ $xeTable.checkSelectionStatus()
221
223
  }
222
- if (mouseConfig && mouseOpts.area && this.handleFilterEvent) {
223
- $xeTable.handleFilterEvent(evnt, params)
224
+ if (mouseConfig && mouseOpts.area && $xeTable.handleFilterEvent) {
225
+ $xeTable.handleFilterEvent(evnt as Event, params)
224
226
  }
225
227
  if (evnt) {
226
- $xeTable.emitEvent('filter-change', params, evnt)
228
+ $xeTable.dispatchEvent('filter-change', params, evnt)
227
229
  }
228
230
  $xeTable.closeFilter()
229
231
  return $xeTable.updateFooter().then(() => {
230
- const { scrollXLoad, scrollYLoad } = this
232
+ const { scrollXLoad, scrollYLoad } = reactData
231
233
  if ((oldScrollXLoad || scrollXLoad) || (oldScrollYLoad || scrollYLoad)) {
232
234
  if ((oldScrollXLoad || scrollXLoad)) {
233
235
  $xeTable.updateScrollXSpace()
@@ -259,6 +261,8 @@ export default {
259
261
  $xeTable.handleColumnConfirmFilter(column, evnt)
260
262
  },
261
263
  handleClearFilter (column: any) {
264
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
265
+
262
266
  if (column) {
263
267
  const { filters, filterRender } = column
264
268
  if (filters) {
@@ -272,7 +276,7 @@ export default {
272
276
  }
273
277
  })
274
278
  if (filterResetMethod) {
275
- filterResetMethod({ options: filters, column, $table: this })
279
+ filterResetMethod({ options: filters, column, $table: $xeTable })
276
280
  }
277
281
  }
278
282
  }
@@ -105,22 +105,29 @@ export default {
105
105
  const params: any = { type: layout, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, columns: this.visibleColumn.slice(0), $event: evnt }
106
106
  if (columnTargetNode.flag) {
107
107
  const cell = columnTargetNode.targetElem
108
- const column = this.getColumnNode(cell).item
108
+ const columnNodeRest = $xeTable.getColumnNode(cell)
109
+ const column = columnNodeRest ? columnNodeRest.item : null
109
110
  let typePrefix = `${layout}-`
110
- Object.assign(params, { column, columnIndex: this.getColumnIndex(column), cell })
111
+ if (column) {
112
+ Object.assign(params, { column, columnIndex: $xeTable.getColumnIndex(column), cell })
113
+ }
111
114
  if (layout === 'body') {
112
- const row = this.getRowNode(cell.parentNode).item
115
+ const rowNodeRest = $xeTable.getRowNode(cell.parentNode)
116
+ const row = rowNodeRest ? rowNodeRest.item : null
113
117
  typePrefix = ''
114
- params.row = row
115
- params.rowIndex = this.getRowIndex(row)
118
+ if (row) {
119
+ params.row = row
120
+ params.rowIndex = $xeTable.getRowIndex(row)
121
+ }
116
122
  }
123
+ const eventType = `${typePrefix}cell-menu` as 'cell-menu' | 'header-cell-menu' | 'footer-cell-menu'
117
124
  this.handleOpenMenuEvent(evnt, layout, params)
118
125
  // 在 v4 中废弃事件 cell-context-menu、header-cell-context-menu、footer-cell-context-menu
119
126
  if (this.$listeners[`${typePrefix}cell-context-menu`]) {
120
127
  warnLog('vxe.error.delEvent', [`${typePrefix}cell-context-menu`, `${typePrefix}cell-menu`])
121
- this.emitEvent(`${typePrefix}cell-context-menu`, params, evnt)
128
+ $xeTable.dispatchEvent(`${typePrefix}cell-context-menu` as any, params, evnt)
122
129
  } else {
123
- this.emitEvent(`${typePrefix}cell-menu`, params, evnt)
130
+ $xeTable.dispatchEvent(eventType, params, evnt)
124
131
  }
125
132
  return
126
133
  } else if (getEventTargetNode(evnt, this.$el, `vxe-table--${layout}-wrapper`, target => target.getAttribute('xid') === tId).flag) {
@@ -271,9 +278,9 @@ export default {
271
278
  // 在 v4 中废弃事件 context-menu-click
272
279
  if (this.$listeners['context-menu-click']) {
273
280
  warnLog('vxe.error.delEvent', ['context-menu-click', 'menu-click'])
274
- this.emitEvent('context-menu-click', params, evnt)
281
+ $xeTable.dispatchEvent('context-menu-click' as any, params, evnt)
275
282
  } else {
276
- this.emitEvent('menu-click', params, evnt)
283
+ $xeTable.dispatchEvent('menu-click', params, evnt)
277
284
  }
278
285
  this.closeMenu()
279
286
  }
@@ -5,7 +5,7 @@ import { scrollToView } from '../../../ui/src/dom'
5
5
  import { handleFieldOrColumn, getRowid } from '../../src/util'
6
6
  import { warnLog, errLog } from '../../../ui/src/log'
7
7
 
8
- import type { VxeTableDefines, TableInternalData, TableReactData } from '../../../../types'
8
+ import type { VxeTableDefines, TableInternalData, TableReactData, VxeTableConstructor, VxeTablePrivateMethods } from '../../../../types'
9
9
 
10
10
  const { getConfig, validators } = VxeUI
11
11
 
@@ -185,10 +185,12 @@ export default {
185
185
  * 聚焦到校验通过的单元格并弹出校验错误提示
186
186
  */
187
187
  handleValidError (params: any) {
188
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
189
+
188
190
  const { validOpts } = this
189
191
  return new Promise<void>(resolve => {
190
192
  if (validOpts.autoPos === false) {
191
- this.emitEvent('valid-error', params)
193
+ $xeTable.dispatchEvent('valid-error', params, null)
192
194
  resolve()
193
195
  } else {
194
196
  this.handleEdit(params, { type: 'valid-error', trigger: 'call' }).then(() => {
@@ -227,7 +229,7 @@ export default {
227
229
  * 返回 Promise 对象,或者使用回调方式
228
230
  */
229
231
  beginValidate (rows: any, cols: VxeTableDefines.ColumnInfo[] | null, cb: any, isFull: any) {
230
- const $xeTable = this
232
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
231
233
  const props = $xeTable
232
234
  const reactData = $xeTable as unknown as TableReactData
233
235
  const internalData = $xeTable as unknown as TableInternalData
@@ -546,6 +548,8 @@ export default {
546
548
  * 弹出校验错误提示
547
549
  */
548
550
  showValidTooltip (params: any) {
551
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
552
+
549
553
  const { $refs, height, validStore, validErrorMaps, tableData, validOpts } = this
550
554
  const { rule, row, column, cell } = params
551
555
  const validTip = $refs.refValidTooltip
@@ -570,7 +574,7 @@ export default {
570
574
  }
571
575
  })
572
576
  }
573
- this.emitEvent('valid-error', params, null)
577
+ $xeTable.dispatchEvent('valid-error', params, null)
574
578
  if (validTip) {
575
579
  if (validTip && (validOpts.message === 'tooltip' || (validOpts.message === 'default' && !height && tableData.length < 2))) {
576
580
  return validTip.open(cell, content)
@@ -55,9 +55,11 @@ export const columnProps = {
55
55
  // 给表尾单元格附加 className
56
56
  footerClassName: [String, Function],
57
57
  // 格式化显示内容
58
- formatter: [Function, Array, String],
58
+ formatter: [Function, Array, String] as PropType<VxeColumnPropTypes.Formatter<any>>,
59
+ // 格式化表头显示内容
60
+ headerFormatter: [Function, Array, String] as PropType<VxeColumnPropTypes.HeaderFormatter>,
59
61
  // 格式化表尾显示内容
60
- footerFormatter: [Function, Array, String],
62
+ footerFormatter: [Function, Array, String] as PropType<VxeColumnPropTypes.FooterFormatter>,
61
63
  // 是否显示间距
62
64
  padding: {
63
65
  type: Boolean as PropType<VxeColumnPropTypes.Padding>,
@@ -93,6 +93,7 @@ export class ColumnInfo {
93
93
  headerClassName: _vm.headerClassName,
94
94
  footerClassName: _vm.footerClassName,
95
95
  formatter,
96
+ headerFormatter: _vm.headerFormatter,
96
97
  footerFormatter: _vm.footerFormatter,
97
98
  padding: _vm.padding,
98
99
  verticalAlign: _vm.verticalAlign,
@@ -34,7 +34,7 @@ function renderRows (h: CreateElement, _vm: any, isOptimizeMode: boolean, tableC
34
34
  const footerCellOpts = $xeTable.computeFooterCellOpts
35
35
  const currCellHeight = getCalcHeight(footerCellOpts.height) || defaultRowHeight
36
36
 
37
- return tableColumn.map((column: any, $columnIndex: any) => {
37
+ return tableColumn.map((column, $columnIndex) => {
38
38
  const { type, showFooterOverflow, footerAlign, align, footerClassName, editRender, cellRender } = column
39
39
  const colid = column.id
40
40
  const colRest = fullColumnIdData[colid] || {}
@@ -240,8 +240,8 @@ export default {
240
240
  default: null
241
241
  }
242
242
  },
243
- mounted (this: any) {
244
- const _vm = this
243
+ mounted () {
244
+ const _vm = this as any
245
245
  const props = _vm
246
246
  const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
247
247
  const tableInternalData = $xeTable as unknown as TableInternalData
@@ -257,8 +257,9 @@ export default {
257
257
  elemStore[`${prefix}xSpace`] = _vm.$refs.refFooterXSpace
258
258
  },
259
259
  destroyed () {
260
- const props = this
261
- const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
260
+ const _vm = this as any
261
+ const props = _vm
262
+ const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
262
263
  const tableInternalData = $xeTable as unknown as TableInternalData
263
264
 
264
265
  const { fixedType } = props
@@ -272,8 +273,9 @@ export default {
272
273
  elemStore[`${prefix}xSpace`] = null
273
274
  },
274
275
  render (h: CreateElement) {
275
- const props = this
276
- const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
276
+ const _vm = this as any
277
+ const props = _vm
278
+ const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
277
279
  const tableProps = $xeTable
278
280
  const tableReactData = $xeTable as unknown as TableReactData
279
281
  const tableInternalData = $xeTable as unknown as TableInternalData
@@ -385,9 +387,9 @@ export default {
385
387
  */
386
388
  h('tfoot', {
387
389
  ref: 'refFooterTFoot'
388
- }, renderHeads(h, this, isOptimizeMode, renderColumnList))
390
+ }, renderHeads(h, _vm, isOptimizeMode, renderColumnList))
389
391
  ])
390
392
  ])
391
393
  ])
392
394
  }
393
- } as any
395
+ }
@@ -2,7 +2,7 @@ import { PropType, CreateElement } from 'vue'
2
2
  import XEUtils from 'xe-utils'
3
3
  import { VxeUI } from '../../ui'
4
4
  import { getClass } from '../../ui/src/utils'
5
- import { getCalcHeight, convertHeaderColumnToRows } from './util'
5
+ import { getCalcHeight, convertHeaderColumnToRows, convertHeaderToGridRows } from './util'
6
6
 
7
7
  import type { VxeTableDefines, VxeTableConstructor, VxeTablePrivateMethods, VxeColumnPropTypes, TableReactData, TableInternalData, VxeComponentStyleType } from '../../../types'
8
8
 
@@ -10,7 +10,7 @@ const { renderer, renderEmptyElement } = VxeUI
10
10
 
11
11
  const cellType = 'header'
12
12
 
13
- const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode: boolean, cols: VxeTableDefines.ColumnInfo[], $rowIndex: number) => {
13
+ function renderRows (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][], $rowIndex: number, cols: VxeTableDefines.ColumnInfo[]) {
14
14
  const props = _vm
15
15
  const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
16
16
  const $xeGrid = $xeTable.$xeGrid
@@ -20,9 +20,9 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
20
20
  const tableInternalData = $xeTable as unknown as TableInternalData
21
21
 
22
22
  const { fixedType } = props
23
- const { resizable: allResizable, columnKey, headerCellClassName, headerCellStyle, showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign, mouseConfig } = tableProps
24
- const { currentColumn, dragCol, scrollXLoad, scrollYLoad, overflowX, tableColumn } = tableReactData
25
- const { fullColumnIdData, scrollXStore } = tableInternalData
23
+ const { resizable: allResizable, columnKey, showCustomHeader, headerCellClassName, headerCellStyle, showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign, mouseConfig } = tableProps
24
+ const { currentColumn, dragCol, scrollXLoad, scrollYLoad, overflowX, mergeHeadFlag, tableColumn } = tableReactData
25
+ const { fullColumnIdData, scrollXStore, mergeHeaderList, mergeHeaderCellMaps } = tableInternalData
26
26
  const virtualXOpts = $xeTable.computeVirtualXOpts
27
27
  const columnOpts = $xeTable.computeColumnOpts
28
28
  const columnDragOpts = $xeTable.computeColumnDragOpts
@@ -31,7 +31,9 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
31
31
  const headerCellOpts = $xeTable.computeHeaderCellOpts
32
32
  const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
33
33
  const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = columnDragOpts
34
- return cols.map((column: any, $columnIndex: any) => {
34
+ const isLastRow = $rowIndex === headerGroups.length - 1
35
+
36
+ return cols.map((column, $columnIndex) => {
35
37
  const { type, showHeaderOverflow, headerAlign, align, filters, headerClassName, editRender, cellRender } = column
36
38
  // const { enabled } = tooltipOpts
37
39
  const colid = column.id
@@ -54,7 +56,7 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
54
56
  hasFilter = filters.some((item: VxeColumnPropTypes.FilterItem) => item.checked)
55
57
  }
56
58
  const columnIndex = colRest.index
57
- const _columnIndex = colRest._index
59
+ const _columnIndex = showCustomHeader ? $columnIndex : colRest._index
58
60
  const cellParams: VxeTableDefines.CellRenderHeaderParams & {
59
61
  $table: VxeTableConstructor & VxeTablePrivateMethods
60
62
  } = {
@@ -73,9 +75,30 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
73
75
  hasFilter
74
76
  }
75
77
  const thAttrs: Record<string, string | number | null> = {
76
- colid,
77
- colspan: column.colSpan > 1 ? column.colSpan : null,
78
- rowspan: column.rowSpan > 1 ? column.rowSpan : null
78
+ colid
79
+ }
80
+ let isMergeCell = false
81
+ // 合并行或列
82
+ if (!showCustomHeader) {
83
+ thAttrs.colspan = column.colSpan > 1 ? column.colSpan : null
84
+ thAttrs.rowspan = column.rowSpan > 1 ? column.rowSpan : null
85
+ }
86
+ if (mergeHeadFlag && mergeHeaderList.length && (showCustomHeader || isLastRow)) {
87
+ const spanRest = mergeHeaderCellMaps[`${$rowIndex}:${showCustomHeader ? $columnIndex : _columnIndex}`]
88
+ if (spanRest) {
89
+ const { rowspan, colspan } = spanRest
90
+ if (!rowspan || !colspan) {
91
+ return null
92
+ }
93
+ if (rowspan > 1) {
94
+ isMergeCell = true
95
+ thAttrs.rowspan = rowspan
96
+ }
97
+ if (colspan > 1) {
98
+ isMergeCell = true
99
+ thAttrs.colspan = colspan
100
+ }
101
+ }
79
102
  }
80
103
  const thOns: any = {
81
104
  click: (evnt: MouseEvent) => $xeTable.triggerHeaderCellClickEvent(evnt, cellParams),
@@ -104,7 +127,7 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
104
127
  const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
105
128
 
106
129
  let isVNPreEmptyStatus = false
107
- if (isOptimizeMode && overflowX && !isGroup) {
130
+ if (isOptimizeMode && overflowX && !isGroup && !isMergeCell) {
108
131
  if (!dragCol || dragCol.id !== colid) {
109
132
  if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
110
133
  isVNPreEmptyStatus = true
@@ -120,7 +143,7 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
120
143
  }
121
144
 
122
145
  return h('th', {
123
- class: ['vxe-table--column vxe-header--column', colid, {
146
+ class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
124
147
  [`col--${headAlign}`]: headAlign,
125
148
  [`col--${type}`]: type,
126
149
  'col--last': isLastColumn,
@@ -128,7 +151,6 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
128
151
  'col--group': isColGroup,
129
152
  'col--ellipsis': hasEllipsis,
130
153
  'fixed--width': !isAutoCellWidth,
131
- 'fixed--hidden': fixedHiddenColumn,
132
154
  'is--padding': isPadding,
133
155
  'is--sortable': column.sortable,
134
156
  'col--filter': !!filters,
@@ -140,7 +162,7 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
140
162
  attrs: thAttrs,
141
163
  style: headerCellStyle ? (XEUtils.isFunction(headerCellStyle) ? headerCellStyle(cellParams) : headerCellStyle) as VxeComponentStyleType : undefined,
142
164
  on: thOns,
143
- key: columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex
165
+ key: showCustomHeader ? `${colid}${$columnIndex}` : (columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex)
144
166
  }, [
145
167
  h('div', {
146
168
  class: ['vxe-cell', {
@@ -160,9 +182,9 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
160
182
  }, column.renderHeader(h, cellParams))
161
183
  ]),
162
184
  /**
163
- * 列宽拖动
164
- */
165
- !fixedHiddenColumn && showResizable
185
+ * 列宽拖动
186
+ */
187
+ !fixedHiddenColumn && showResizable && (!showCustomHeader || isLastRow)
166
188
  ? h('div', {
167
189
  class: 'vxe-cell--col-resizable',
168
190
  on: {
@@ -175,7 +197,7 @@ const renderRows = (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode
175
197
  })
176
198
  }
177
199
 
178
- function renderHeads (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode: boolean, headerGroups: any[]) {
200
+ function renderHeads (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][]) {
179
201
  const props = _vm
180
202
  const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
181
203
  const tableProps = $xeTable
@@ -194,7 +216,7 @@ function renderHeads (h: CreateElement, _vm: any, isGroup: boolean, isOptimizeMo
194
216
  headerRowClassName ? XEUtils.isFunction(headerRowClassName) ? headerRowClassName(params) : headerRowClassName : ''
195
217
  ],
196
218
  style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) as VxeComponentStyleType : undefined
197
- }, renderRows(h, _vm, isGroup, isOptimizeMode, cols, $rowIndex))
219
+ }, renderRows(h, _vm, isGroup, isOptimizeMode, headerGroups, $rowIndex, cols))
198
220
  })
199
221
  }
200
222
 
@@ -216,15 +238,18 @@ export default {
216
238
  }
217
239
  },
218
240
  watch: {
219
- tableColumn (this: any) {
220
- this.uploadColumn()
241
+ tableColumn () {
242
+ const _vm = this as any
243
+
244
+ _vm.uploadColumn()
221
245
  }
222
246
  },
223
- created (this: any) {
224
- this.uploadColumn()
247
+ created () {
248
+ const _vm = this as any
249
+ _vm.uploadColumn()
225
250
  },
226
251
  mounted () {
227
- const _vm = this
252
+ const _vm = this as any
228
253
  const props = _vm
229
254
  const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
230
255
  const internalData = $xeTable as unknown as TableInternalData
@@ -241,8 +266,9 @@ export default {
241
266
  elemStore[`${prefix}repair`] = _vm.$refs.refHeaderBorderRepair
242
267
  },
243
268
  destroyed () {
244
- const props = this
245
- const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
269
+ const _vm = this as any
270
+ const props = _vm
271
+ const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
246
272
  const internalData = $xeTable as unknown as TableInternalData
247
273
 
248
274
  const { fixedType } = props
@@ -257,15 +283,16 @@ export default {
257
283
  elemStore[`${prefix}repair`] = null
258
284
  },
259
285
  render (h: CreateElement) {
260
- const props = this
261
- const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
286
+ const _vm = this as any
287
+ const props = _vm
288
+ const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
262
289
  const tableProps = $xeTable
263
290
  const tableReactData = $xeTable as unknown as TableReactData
264
291
  const tableInternalData = $xeTable as unknown as TableInternalData
265
292
 
266
293
  const { xID } = $xeTable
267
294
  const { fixedType, fixedColumn, tableColumn } = props
268
- const { headerColumn } = this
295
+ const { headerColumn } = _vm
269
296
 
270
297
  const { mouseConfig, showHeaderOverflow: allColumnHeaderOverflow, spanMethod, footerSpanMethod } = tableProps
271
298
  const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData
@@ -382,7 +409,7 @@ export default {
382
409
  */
383
410
  h('thead', {
384
411
  ref: 'refHeaderTHead'
385
- }, renderHeads(h, this, isGroup, isOptimizeMode, renderHeaderList))
412
+ }, renderHeads(h, _vm, isGroup, isOptimizeMode, renderHeaderList))
386
413
  ]),
387
414
  mouseConfig && mouseOpts.area
388
415
  ? h('div', {
@@ -413,11 +440,26 @@ export default {
413
440
  },
414
441
  methods: {
415
442
  uploadColumn () {
416
- const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
443
+ const _vm = this as any
444
+ const $xeTable = _vm.$parent as VxeTableConstructor & VxeTablePrivateMethods
445
+ const tableProps = $xeTable
417
446
  const tableReactData = $xeTable as unknown as TableReactData
447
+ const tableInternalData = $xeTable as unknown as TableInternalData
418
448
 
449
+ const props = _vm
450
+
451
+ const { showCustomHeader } = tableProps
452
+ const { collectColumn, visibleColumn } = tableInternalData
453
+ const { tableGroupColumn } = props
419
454
  const { isGroup } = tableReactData
420
- this.headerColumn = isGroup ? convertHeaderColumnToRows(this.tableGroupColumn) : []
455
+ let spanColumns: VxeTableDefines.ColumnInfo[][] = isGroup ? convertHeaderColumnToRows(tableGroupColumn) : []
456
+ let visibleColgroups: VxeTableDefines.ColumnInfo[][] = []
457
+ if (showCustomHeader && spanColumns.length > 1) {
458
+ visibleColgroups = convertHeaderToGridRows(spanColumns)
459
+ spanColumns = visibleColgroups
460
+ }
461
+ _vm.headerColumn = spanColumns
462
+ $xeTable.dispatchEvent('columns-change', { visibleColgroups, collectColumn, visibleColumn }, null)
421
463
  }
422
- } as any
423
- } as any
464
+ }
465
+ }