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
@@ -94,14 +94,18 @@ function handleInsertRowAt($xeTable, records, targetRow, isInsertNextRow) {
94
94
  const internalData = $xeTable;
95
95
  const { treeConfig } = props;
96
96
  const { isRowGroupStatus } = reactData;
97
- const { tableFullTreeData, afterFullData, mergeBodyList, tableFullData, fullDataRowIdData, fullAllDataRowIdData, insertRowMaps } = internalData;
97
+ const { tableFullTreeData, afterFullData, mergeBodyList, tableFullData, fullDataRowIdData, fullAllDataRowIdData, insertRowMaps, removeRowMaps } = internalData;
98
98
  const treeOpts = $xeTable.computeTreeOpts;
99
- const { transform, rowField, mapChildrenField } = treeOpts;
99
+ const { transform, parentField, rowField, mapChildrenField } = treeOpts;
100
100
  const childrenField = treeOpts.children || treeOpts.childrenField;
101
101
  if (!XEUtils.isArray(records)) {
102
102
  records = [records];
103
103
  }
104
104
  const newRecords = $xeTable.defineField(records.map(record => Object.assign(treeConfig && transform ? { [mapChildrenField]: [], [childrenField]: [] } : {}, record)));
105
+ let treeRecords = [];
106
+ if (treeConfig && transform) {
107
+ treeRecords = XEUtils.toArrayTree(newRecords, { key: rowField, parentKey: parentField, children: childrenField });
108
+ }
105
109
  if (XEUtils.eqNull(targetRow)) {
106
110
  // 如果为虚拟树
107
111
  if (treeConfig && transform) {
@@ -161,41 +165,50 @@ function handleInsertRowAt($xeTable, records, targetRow, isInsertNextRow) {
161
165
  else {
162
166
  // 如果为虚拟树
163
167
  if (treeConfig && transform) {
164
- const matchMapObj = XEUtils.findTree(tableFullTreeData, (item) => targetRow[rowField] === item[rowField], { children: mapChildrenField });
168
+ const matchMapObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: mapChildrenField });
165
169
  if (matchMapObj) {
166
170
  const { parent: parentRow } = matchMapObj;
167
171
  const parentMapChilds = parentRow ? parentRow[mapChildrenField] : tableFullTreeData;
168
172
  const parentRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)];
169
173
  const parentLevel = parentRest ? parentRest.level : 0;
170
- newRecords.forEach((item, i) => {
171
- const rowid = getRowid($xeTable, item);
172
- if (item[treeOpts.parentField]) {
173
- if (parentRow && item[treeOpts.parentField] !== parentRow[rowField]) {
174
- errLog('vxe.error.errProp', [`${treeOpts.parentField}=${item[treeOpts.parentField]}`, `${treeOpts.parentField}=${parentRow[rowField]}`]);
174
+ treeRecords.forEach((row, i) => {
175
+ if (parentRow) {
176
+ if (row[parentField] !== parentRow[rowField]) {
177
+ row[parentField] = parentRow[rowField];
178
+ errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, `${parentField}=${parentRow[rowField]}`]);
175
179
  }
176
180
  }
177
- if (parentRow) {
178
- item[treeOpts.parentField] = parentRow[rowField];
181
+ else {
182
+ if (row[parentField] !== null) {
183
+ row[parentField] = null;
184
+ errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, 'null']);
185
+ }
179
186
  }
180
187
  let targetIndex = matchMapObj.index + i;
181
188
  if (isInsertNextRow) {
182
189
  targetIndex = targetIndex + 1;
183
190
  }
184
- parentMapChilds.splice(targetIndex, 0, item);
191
+ parentMapChilds.splice(targetIndex, 0, row);
192
+ });
193
+ XEUtils.eachTree(treeRecords, (item) => {
194
+ const rowid = getRowid($xeTable, item);
185
195
  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 };
196
+ if (item[childrenField]) {
197
+ item[mapChildrenField] = item[childrenField];
198
+ }
186
199
  fullDataRowIdData[rowid] = rest;
187
200
  fullAllDataRowIdData[rowid] = rest;
188
- });
201
+ }, { children: childrenField });
189
202
  // 源
190
203
  if (parentRow) {
191
- const matchObj = XEUtils.findTree(tableFullTreeData, (item) => targetRow[rowField] === item[rowField], { children: childrenField });
204
+ const matchObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: childrenField });
192
205
  if (matchObj) {
193
206
  const parentChilds = matchObj.items;
194
207
  let targetIndex = matchObj.index;
195
208
  if (isInsertNextRow) {
196
209
  targetIndex = targetIndex + 1;
197
210
  }
198
- parentChilds.splice(targetIndex, 0, ...newRecords);
211
+ parentChilds.splice(targetIndex, 0, ...treeRecords);
199
212
  }
200
213
  }
201
214
  }
@@ -230,7 +243,7 @@ function handleInsertRowAt($xeTable, records, targetRow, isInsertNextRow) {
230
243
  afIndex = Math.min(afterFullData.length, afIndex + 1);
231
244
  }
232
245
  if (afIndex === -1) {
233
- throw new Error(errLog('vxe.error.unableInsert'));
246
+ throw new Error(getI18n('vxe.error.unableInsert'));
234
247
  }
235
248
  afterFullData.splice(afIndex, 0, ...newRecords);
236
249
  const tfIndex = $xeTable.findRowIndexOf(tableFullData, targetRow);
@@ -253,10 +266,27 @@ function handleInsertRowAt($xeTable, records, targetRow, isInsertNextRow) {
253
266
  }
254
267
  }
255
268
  }
256
- newRecords.forEach(newRow => {
269
+ const handleStatus = (newRow) => {
257
270
  const rowid = getRowid($xeTable, newRow);
258
- insertRowMaps[rowid] = newRow;
259
- });
271
+ // 如果是被删除的数据,则还原状态
272
+ if (removeRowMaps[rowid]) {
273
+ delete removeRowMaps[rowid];
274
+ if (insertRowMaps[rowid]) {
275
+ delete insertRowMaps[rowid];
276
+ }
277
+ }
278
+ else {
279
+ insertRowMaps[rowid] = newRow;
280
+ }
281
+ };
282
+ // 如果为虚拟树
283
+ if (treeConfig && transform) {
284
+ XEUtils.eachTree(treeRecords, handleStatus, { children: mapChildrenField });
285
+ }
286
+ else {
287
+ newRecords.forEach(handleStatus);
288
+ }
289
+ reactData.removeRowFlag++;
260
290
  reactData.insertRowFlag++;
261
291
  $xeTable.cacheRowMap(false);
262
292
  $xeTable.updateScrollYStatus();
@@ -800,7 +830,12 @@ export default {
800
830
  const { editStore } = reactData;
801
831
  const { row, column } = editStore.actived;
802
832
  if (column && row) {
803
- return { row, column };
833
+ return {
834
+ row,
835
+ rowIndex: $xeTable.getRowIndex(row),
836
+ column,
837
+ columnIndex: $xeTable.getColumnIndex(column)
838
+ };
804
839
  }
805
840
  return null;
806
841
  },
@@ -988,7 +1023,10 @@ export default {
988
1023
  const { editStore } = reactData;
989
1024
  const { row, column } = editStore.selected;
990
1025
  if (row && column) {
991
- return { row, column };
1026
+ return {
1027
+ row,
1028
+ column
1029
+ };
992
1030
  }
993
1031
  return null;
994
1032
  },
@@ -11,11 +11,12 @@ export default {
11
11
  * @param column
12
12
  */
13
13
  _openFilter(fieldOrColumn) {
14
+ const $xeTable = this;
14
15
  const column = handleFieldOrColumn(this, fieldOrColumn);
15
16
  if (column && column.filters) {
16
17
  const { elemStore } = this;
17
18
  const { fixed } = column;
18
- return this.scrollToColumn(column).then(() => {
19
+ return $xeTable.scrollToColumn(column).then(() => {
19
20
  const headerWrapperElem = elemStore[`${fixed || 'main'}-header-wrapper`] || elemStore['main-header-wrapper'];
20
21
  if (headerWrapperElem) {
21
22
  const filterBtnElem = headerWrapperElem.querySelector(`.vxe-header--column.${column.id} .vxe-cell--filter`);
@@ -23,7 +24,7 @@ export default {
23
24
  }
24
25
  });
25
26
  }
26
- return this.$nextTick();
27
+ return $xeTable.$nextTick();
27
28
  },
28
29
  /**
29
30
  * 修改筛选条件列表
@@ -206,22 +207,22 @@ export default {
206
207
  datas.push(item.data);
207
208
  }
208
209
  });
209
- const filterList = this.getCheckedFilters();
210
- const params = { $table: this, $event: evnt, column, field, property: field, values, datas, filters: filterList, filterList };
210
+ const filterList = $xeTable.getCheckedFilters();
211
+ const params = { $table: $xeTable, $event: evnt, column, field, property: field, values, datas, filters: filterList, filterList };
211
212
  // 如果是服务端筛选,则跳过本地筛选处理
212
213
  if (!filterOpts.remote) {
213
- this.handleTableData(true);
214
- this.checkSelectionStatus();
214
+ $xeTable.handleTableData(true);
215
+ $xeTable.checkSelectionStatus();
215
216
  }
216
- if (mouseConfig && mouseOpts.area && this.handleFilterEvent) {
217
+ if (mouseConfig && mouseOpts.area && $xeTable.handleFilterEvent) {
217
218
  $xeTable.handleFilterEvent(evnt, params);
218
219
  }
219
220
  if (evnt) {
220
- $xeTable.emitEvent('filter-change', params, evnt);
221
+ $xeTable.dispatchEvent('filter-change', params, evnt);
221
222
  }
222
223
  $xeTable.closeFilter();
223
224
  return $xeTable.updateFooter().then(() => {
224
- const { scrollXLoad, scrollYLoad } = this;
225
+ const { scrollXLoad, scrollYLoad } = reactData;
225
226
  if ((oldScrollXLoad || scrollXLoad) || (oldScrollYLoad || scrollYLoad)) {
226
227
  if ((oldScrollXLoad || scrollXLoad)) {
227
228
  $xeTable.updateScrollXSpace();
@@ -252,6 +253,7 @@ export default {
252
253
  $xeTable.handleColumnConfirmFilter(column, evnt);
253
254
  },
254
255
  handleClearFilter(column) {
256
+ const $xeTable = this;
255
257
  if (column) {
256
258
  const { filters, filterRender } = column;
257
259
  if (filters) {
@@ -265,7 +267,7 @@ export default {
265
267
  }
266
268
  });
267
269
  if (filterResetMethod) {
268
- filterResetMethod({ options: filters, column, $table: this });
270
+ filterResetMethod({ options: filters, column, $table: $xeTable });
269
271
  }
270
272
  }
271
273
  }
@@ -104,23 +104,30 @@ export default {
104
104
  const params = { type: layout, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, columns: this.visibleColumn.slice(0), $event: evnt };
105
105
  if (columnTargetNode.flag) {
106
106
  const cell = columnTargetNode.targetElem;
107
- const column = this.getColumnNode(cell).item;
107
+ const columnNodeRest = $xeTable.getColumnNode(cell);
108
+ const column = columnNodeRest ? columnNodeRest.item : null;
108
109
  let typePrefix = `${layout}-`;
109
- Object.assign(params, { column, columnIndex: this.getColumnIndex(column), cell });
110
+ if (column) {
111
+ Object.assign(params, { column, columnIndex: $xeTable.getColumnIndex(column), cell });
112
+ }
110
113
  if (layout === 'body') {
111
- const row = this.getRowNode(cell.parentNode).item;
114
+ const rowNodeRest = $xeTable.getRowNode(cell.parentNode);
115
+ const row = rowNodeRest ? rowNodeRest.item : null;
112
116
  typePrefix = '';
113
- params.row = row;
114
- params.rowIndex = this.getRowIndex(row);
117
+ if (row) {
118
+ params.row = row;
119
+ params.rowIndex = $xeTable.getRowIndex(row);
120
+ }
115
121
  }
122
+ const eventType = `${typePrefix}cell-menu`;
116
123
  this.handleOpenMenuEvent(evnt, layout, params);
117
124
  // 在 v4 中废弃事件 cell-context-menu、header-cell-context-menu、footer-cell-context-menu
118
125
  if (this.$listeners[`${typePrefix}cell-context-menu`]) {
119
126
  warnLog('vxe.error.delEvent', [`${typePrefix}cell-context-menu`, `${typePrefix}cell-menu`]);
120
- this.emitEvent(`${typePrefix}cell-context-menu`, params, evnt);
127
+ $xeTable.dispatchEvent(`${typePrefix}cell-context-menu`, params, evnt);
121
128
  }
122
129
  else {
123
- this.emitEvent(`${typePrefix}cell-menu`, params, evnt);
130
+ $xeTable.dispatchEvent(eventType, params, evnt);
124
131
  }
125
132
  return;
126
133
  }
@@ -275,10 +282,10 @@ export default {
275
282
  // 在 v4 中废弃事件 context-menu-click
276
283
  if (this.$listeners['context-menu-click']) {
277
284
  warnLog('vxe.error.delEvent', ['context-menu-click', 'menu-click']);
278
- this.emitEvent('context-menu-click', params, evnt);
285
+ $xeTable.dispatchEvent('context-menu-click', params, evnt);
279
286
  }
280
287
  else {
281
- this.emitEvent('menu-click', params, evnt);
288
+ $xeTable.dispatchEvent('menu-click', params, evnt);
282
289
  }
283
290
  this.closeMenu();
284
291
  }
@@ -181,10 +181,11 @@ export default {
181
181
  * 聚焦到校验通过的单元格并弹出校验错误提示
182
182
  */
183
183
  handleValidError(params) {
184
+ const $xeTable = this;
184
185
  const { validOpts } = this;
185
186
  return new Promise(resolve => {
186
187
  if (validOpts.autoPos === false) {
187
- this.emitEvent('valid-error', params);
188
+ $xeTable.dispatchEvent('valid-error', params, null);
188
189
  resolve();
189
190
  }
190
191
  else {
@@ -547,6 +548,7 @@ export default {
547
548
  * 弹出校验错误提示
548
549
  */
549
550
  showValidTooltip(params) {
551
+ const $xeTable = this;
550
552
  const { $refs, height, validStore, validErrorMaps, tableData, validOpts } = this;
551
553
  const { rule, row, column, cell } = params;
552
554
  const validTip = $refs.refValidTooltip;
@@ -572,7 +574,7 @@ export default {
572
574
  }
573
575
  });
574
576
  }
575
- this.emitEvent('valid-error', params, null);
577
+ $xeTable.dispatchEvent('valid-error', params, null);
576
578
  if (validTip) {
577
579
  if (validTip && (validOpts.message === 'tooltip' || (validOpts.message === 'default' && !height && tableData.length < 2))) {
578
580
  return validTip.open(cell, content);
@@ -52,6 +52,8 @@ export const columnProps = {
52
52
  footerClassName: [String, Function],
53
53
  // 格式化显示内容
54
54
  formatter: [Function, Array, String],
55
+ // 格式化表头显示内容
56
+ headerFormatter: [Function, Array, String],
55
57
  // 格式化表尾显示内容
56
58
  footerFormatter: [Function, Array, String],
57
59
  // 是否显示间距
@@ -85,6 +85,7 @@ export class ColumnInfo {
85
85
  headerClassName: _vm.headerClassName,
86
86
  footerClassName: _vm.footerClassName,
87
87
  formatter,
88
+ headerFormatter: _vm.headerFormatter,
88
89
  footerFormatter: _vm.footerFormatter,
89
90
  padding: _vm.padding,
90
91
  verticalAlign: _vm.verticalAlign,
@@ -240,8 +240,9 @@ export default {
240
240
  elemStore[`${prefix}xSpace`] = _vm.$refs.refFooterXSpace;
241
241
  },
242
242
  destroyed() {
243
- const props = this;
244
- const $xeTable = this.$parent;
243
+ const _vm = this;
244
+ const props = _vm;
245
+ const $xeTable = _vm.$parent;
245
246
  const tableInternalData = $xeTable;
246
247
  const { fixedType } = props;
247
248
  const { elemStore } = tableInternalData;
@@ -254,8 +255,9 @@ export default {
254
255
  elemStore[`${prefix}xSpace`] = null;
255
256
  },
256
257
  render(h) {
257
- const props = this;
258
- const $xeTable = this.$parent;
258
+ const _vm = this;
259
+ const props = _vm;
260
+ const $xeTable = _vm.$parent;
259
261
  const tableProps = $xeTable;
260
262
  const tableReactData = $xeTable;
261
263
  const tableInternalData = $xeTable;
@@ -362,7 +364,7 @@ export default {
362
364
  */
363
365
  h('tfoot', {
364
366
  ref: 'refFooterTFoot'
365
- }, renderHeads(h, this, isOptimizeMode, renderColumnList))
367
+ }, renderHeads(h, _vm, isOptimizeMode, renderColumnList))
366
368
  ])
367
369
  ])
368
370
  ]);
@@ -1,10 +1,10 @@
1
1
  import XEUtils from 'xe-utils';
2
2
  import { VxeUI } from '../../ui';
3
3
  import { getClass } from '../../ui/src/utils';
4
- import { getCalcHeight, convertHeaderColumnToRows } from './util';
4
+ import { getCalcHeight, convertHeaderColumnToRows, convertHeaderToGridRows } from './util';
5
5
  const { renderer, renderEmptyElement } = VxeUI;
6
6
  const cellType = 'header';
7
- const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
7
+ function renderRows(h, _vm, isGroup, isOptimizeMode, headerGroups, $rowIndex, cols) {
8
8
  const props = _vm;
9
9
  const $xeTable = _vm.$parent;
10
10
  const $xeGrid = $xeTable.$xeGrid;
@@ -13,9 +13,9 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
13
13
  const tableReactData = $xeTable;
14
14
  const tableInternalData = $xeTable;
15
15
  const { fixedType } = props;
16
- const { resizable: allResizable, columnKey, headerCellClassName, headerCellStyle, showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign, mouseConfig } = tableProps;
17
- const { currentColumn, dragCol, scrollXLoad, scrollYLoad, overflowX, tableColumn } = tableReactData;
18
- const { fullColumnIdData, scrollXStore } = tableInternalData;
16
+ const { resizable: allResizable, columnKey, showCustomHeader, headerCellClassName, headerCellStyle, showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign, mouseConfig } = tableProps;
17
+ const { currentColumn, dragCol, scrollXLoad, scrollYLoad, overflowX, mergeHeadFlag, tableColumn } = tableReactData;
18
+ const { fullColumnIdData, scrollXStore, mergeHeaderList, mergeHeaderCellMaps } = tableInternalData;
19
19
  const virtualXOpts = $xeTable.computeVirtualXOpts;
20
20
  const columnOpts = $xeTable.computeColumnOpts;
21
21
  const columnDragOpts = $xeTable.computeColumnDragOpts;
@@ -24,6 +24,7 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
24
24
  const headerCellOpts = $xeTable.computeHeaderCellOpts;
25
25
  const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight;
26
26
  const { disabledMethod: dragDisabledMethod, isCrossDrag, isPeerDrag } = columnDragOpts;
27
+ const isLastRow = $rowIndex === headerGroups.length - 1;
27
28
  return cols.map((column, $columnIndex) => {
28
29
  const { type, showHeaderOverflow, headerAlign, align, filters, headerClassName, editRender, cellRender } = column;
29
30
  // const { enabled } = tooltipOpts
@@ -47,7 +48,7 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
47
48
  hasFilter = filters.some((item) => item.checked);
48
49
  }
49
50
  const columnIndex = colRest.index;
50
- const _columnIndex = colRest._index;
51
+ const _columnIndex = showCustomHeader ? $columnIndex : colRest._index;
51
52
  const cellParams = {
52
53
  $table: $xeTable,
53
54
  $grid: $xeGrid,
@@ -64,10 +65,31 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
64
65
  hasFilter
65
66
  };
66
67
  const thAttrs = {
67
- colid,
68
- colspan: column.colSpan > 1 ? column.colSpan : null,
69
- rowspan: column.rowSpan > 1 ? column.rowSpan : null
68
+ colid
70
69
  };
70
+ let isMergeCell = false;
71
+ // 合并行或列
72
+ if (!showCustomHeader) {
73
+ thAttrs.colspan = column.colSpan > 1 ? column.colSpan : null;
74
+ thAttrs.rowspan = column.rowSpan > 1 ? column.rowSpan : null;
75
+ }
76
+ if (mergeHeadFlag && mergeHeaderList.length && (showCustomHeader || isLastRow)) {
77
+ const spanRest = mergeHeaderCellMaps[`${$rowIndex}:${showCustomHeader ? $columnIndex : _columnIndex}`];
78
+ if (spanRest) {
79
+ const { rowspan, colspan } = spanRest;
80
+ if (!rowspan || !colspan) {
81
+ return null;
82
+ }
83
+ if (rowspan > 1) {
84
+ isMergeCell = true;
85
+ thAttrs.rowspan = rowspan;
86
+ }
87
+ if (colspan > 1) {
88
+ isMergeCell = true;
89
+ thAttrs.colspan = colspan;
90
+ }
91
+ }
92
+ }
71
93
  const thOns = {
72
94
  click: (evnt) => $xeTable.triggerHeaderCellClickEvent(evnt, cellParams),
73
95
  dblclick: (evnt) => $xeTable.triggerHeaderCellDblclickEvent(evnt, cellParams)
@@ -94,7 +116,7 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
94
116
  const showResizable = (XEUtils.isBoolean(column.resizable) ? column.resizable : (columnOpts.resizable || allResizable));
95
117
  const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto');
96
118
  let isVNPreEmptyStatus = false;
97
- if (isOptimizeMode && overflowX && !isGroup) {
119
+ if (isOptimizeMode && overflowX && !isGroup && !isMergeCell) {
98
120
  if (!dragCol || dragCol.id !== colid) {
99
121
  if (scrollXLoad && tableColumn.length > 10 && !column.fixed && !virtualXOpts.immediate && (_columnIndex < scrollXStore.visibleStartIndex - scrollXStore.preloadSize || _columnIndex > scrollXStore.visibleEndIndex + scrollXStore.preloadSize)) {
100
122
  isVNPreEmptyStatus = true;
@@ -109,7 +131,7 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
109
131
  tcStyle.minHeight = `${currCellHeight}px`;
110
132
  }
111
133
  return h('th', {
112
- class: ['vxe-table--column vxe-header--column', colid, {
134
+ class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
113
135
  [`col--${headAlign}`]: headAlign,
114
136
  [`col--${type}`]: type,
115
137
  'col--last': isLastColumn,
@@ -117,7 +139,6 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
117
139
  'col--group': isColGroup,
118
140
  'col--ellipsis': hasEllipsis,
119
141
  'fixed--width': !isAutoCellWidth,
120
- 'fixed--hidden': fixedHiddenColumn,
121
142
  'is--padding': isPadding,
122
143
  'is--sortable': column.sortable,
123
144
  'col--filter': !!filters,
@@ -129,7 +150,7 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
129
150
  attrs: thAttrs,
130
151
  style: headerCellStyle ? (XEUtils.isFunction(headerCellStyle) ? headerCellStyle(cellParams) : headerCellStyle) : undefined,
131
152
  on: thOns,
132
- key: columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex
153
+ key: showCustomHeader ? `${colid}${$columnIndex}` : (columnKey || scrollXLoad || scrollYLoad || columnOpts.useKey || columnOpts.drag || isColGroup ? colid : $columnIndex)
133
154
  }, [
134
155
  h('div', {
135
156
  class: ['vxe-cell', {
@@ -149,9 +170,9 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
149
170
  }, column.renderHeader(h, cellParams))
150
171
  ]),
151
172
  /**
152
- * 列宽拖动
153
- */
154
- !fixedHiddenColumn && showResizable
173
+ * 列宽拖动
174
+ */
175
+ !fixedHiddenColumn && showResizable && (!showCustomHeader || isLastRow)
155
176
  ? h('div', {
156
177
  class: 'vxe-cell--col-resizable',
157
178
  on: {
@@ -162,7 +183,7 @@ const renderRows = (h, _vm, isGroup, isOptimizeMode, cols, $rowIndex) => {
162
183
  : renderEmptyElement($xeTable)
163
184
  ]);
164
185
  });
165
- };
186
+ }
166
187
  function renderHeads(h, _vm, isGroup, isOptimizeMode, headerGroups) {
167
188
  const props = _vm;
168
189
  const $xeTable = _vm.$parent;
@@ -178,7 +199,7 @@ function renderHeads(h, _vm, isGroup, isOptimizeMode, headerGroups) {
178
199
  headerRowClassName ? XEUtils.isFunction(headerRowClassName) ? headerRowClassName(params) : headerRowClassName : ''
179
200
  ],
180
201
  style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) : undefined
181
- }, renderRows(h, _vm, isGroup, isOptimizeMode, cols, $rowIndex));
202
+ }, renderRows(h, _vm, isGroup, isOptimizeMode, headerGroups, $rowIndex, cols));
182
203
  });
183
204
  }
184
205
  export default {
@@ -200,11 +221,13 @@ export default {
200
221
  },
201
222
  watch: {
202
223
  tableColumn() {
203
- this.uploadColumn();
224
+ const _vm = this;
225
+ _vm.uploadColumn();
204
226
  }
205
227
  },
206
228
  created() {
207
- this.uploadColumn();
229
+ const _vm = this;
230
+ _vm.uploadColumn();
208
231
  },
209
232
  mounted() {
210
233
  const _vm = this;
@@ -223,8 +246,9 @@ export default {
223
246
  elemStore[`${prefix}repair`] = _vm.$refs.refHeaderBorderRepair;
224
247
  },
225
248
  destroyed() {
226
- const props = this;
227
- const $xeTable = this.$parent;
249
+ const _vm = this;
250
+ const props = _vm;
251
+ const $xeTable = _vm.$parent;
228
252
  const internalData = $xeTable;
229
253
  const { fixedType } = props;
230
254
  const { elemStore } = internalData;
@@ -238,14 +262,15 @@ export default {
238
262
  elemStore[`${prefix}repair`] = null;
239
263
  },
240
264
  render(h) {
241
- const props = this;
242
- const $xeTable = this.$parent;
265
+ const _vm = this;
266
+ const props = _vm;
267
+ const $xeTable = _vm.$parent;
243
268
  const tableProps = $xeTable;
244
269
  const tableReactData = $xeTable;
245
270
  const tableInternalData = $xeTable;
246
271
  const { xID } = $xeTable;
247
272
  const { fixedType, fixedColumn, tableColumn } = props;
248
- const { headerColumn } = this;
273
+ const { headerColumn } = _vm;
249
274
  const { mouseConfig, showHeaderOverflow: allColumnHeaderOverflow, spanMethod, footerSpanMethod } = tableProps;
250
275
  const { isGroup, isColLoading, overflowX, scrollXLoad, dragCol } = tableReactData;
251
276
  const { visibleColumn, fullColumnIdData } = tableInternalData;
@@ -358,7 +383,7 @@ export default {
358
383
  */
359
384
  h('thead', {
360
385
  ref: 'refHeaderTHead'
361
- }, renderHeads(h, this, isGroup, isOptimizeMode, renderHeaderList))
386
+ }, renderHeads(h, _vm, isGroup, isOptimizeMode, renderHeaderList))
362
387
  ]),
363
388
  mouseConfig && mouseOpts.area
364
389
  ? h('div', {
@@ -389,10 +414,24 @@ export default {
389
414
  },
390
415
  methods: {
391
416
  uploadColumn() {
392
- const $xeTable = this.$parent;
417
+ const _vm = this;
418
+ const $xeTable = _vm.$parent;
419
+ const tableProps = $xeTable;
393
420
  const tableReactData = $xeTable;
421
+ const tableInternalData = $xeTable;
422
+ const props = _vm;
423
+ const { showCustomHeader } = tableProps;
424
+ const { collectColumn, visibleColumn } = tableInternalData;
425
+ const { tableGroupColumn } = props;
394
426
  const { isGroup } = tableReactData;
395
- this.headerColumn = isGroup ? convertHeaderColumnToRows(this.tableGroupColumn) : [];
427
+ let spanColumns = isGroup ? convertHeaderColumnToRows(tableGroupColumn) : [];
428
+ let visibleColgroups = [];
429
+ if (showCustomHeader && spanColumns.length > 1) {
430
+ visibleColgroups = convertHeaderToGridRows(spanColumns);
431
+ spanColumns = visibleColgroups;
432
+ }
433
+ _vm.headerColumn = spanColumns;
434
+ $xeTable.dispatchEvent('columns-change', { visibleColgroups, collectColumn, visibleColumn }, null);
396
435
  }
397
436
  }
398
437
  };