vxe-table 3.18.1 → 3.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/es/grid/src/grid.js +5 -1
  2. package/es/index.css +1 -1
  3. package/es/index.min.css +1 -1
  4. package/es/style.css +1 -1
  5. package/es/style.min.css +1 -1
  6. package/es/table/module/menu/mixin.js +67 -43
  7. package/es/table/module/menu/panel.js +10 -8
  8. package/es/table/src/body.js +12 -14
  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 +233 -39
  14. package/es/table/src/props.js +23 -6
  15. package/es/table/src/table.js +43 -19
  16. package/es/table/src/util.js +70 -2
  17. package/es/table/style.css +11 -21
  18. package/es/table/style.min.css +1 -1
  19. package/es/ui/index.js +1 -1
  20. package/es/ui/src/log.js +1 -1
  21. package/es/ui/src/vn.js +16 -11
  22. package/es/vxe-table/style.css +11 -21
  23. package/es/vxe-table/style.min.css +1 -1
  24. package/lib/grid/src/grid.js +6 -0
  25. package/lib/grid/src/grid.min.js +1 -1
  26. package/lib/index.css +1 -1
  27. package/lib/index.min.css +1 -1
  28. package/lib/index.umd.js +610 -185
  29. package/lib/index.umd.min.js +1 -1
  30. package/lib/style.css +1 -1
  31. package/lib/style.min.css +1 -1
  32. package/lib/table/module/menu/mixin.js +84 -58
  33. package/lib/table/module/menu/mixin.min.js +1 -1
  34. package/lib/table/module/menu/panel.js +11 -10
  35. package/lib/table/module/menu/panel.min.js +1 -1
  36. package/lib/table/src/body.js +11 -13
  37. package/lib/table/src/body.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 +259 -42
  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/table.js +46 -16
  50. package/lib/table/src/table.min.js +1 -1
  51. package/lib/table/src/util.js +74 -2
  52. package/lib/table/src/util.min.js +1 -1
  53. package/lib/table/style/style.css +11 -21
  54. package/lib/table/style/style.min.css +1 -1
  55. package/lib/ui/index.js +1 -1
  56. package/lib/ui/index.min.js +1 -1
  57. package/lib/ui/src/log.js +1 -1
  58. package/lib/ui/src/log.min.js +1 -1
  59. package/lib/ui/src/vn.js +16 -10
  60. package/lib/ui/src/vn.min.js +1 -1
  61. package/lib/vxe-table/style/style.css +11 -21
  62. package/lib/vxe-table/style/style.min.css +1 -1
  63. package/package.json +1 -1
  64. package/packages/grid/src/grid.ts +5 -1
  65. package/packages/table/module/menu/mixin.ts +79 -50
  66. package/packages/table/module/menu/panel.ts +11 -9
  67. package/packages/table/src/body.ts +11 -13
  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 +245 -40
  73. package/packages/table/src/props.ts +29 -12
  74. package/packages/table/src/table.ts +53 -16
  75. package/packages/table/src/util.ts +76 -2
  76. package/packages/ui/src/vn.ts +16 -11
  77. package/styles/components/table.scss +33 -56
  78. /package/es/{iconfont.1756272539382.ttf → iconfont.1756629700380.ttf} +0 -0
  79. /package/es/{iconfont.1756272539382.woff → iconfont.1756629700380.woff} +0 -0
  80. /package/es/{iconfont.1756272539382.woff2 → iconfont.1756629700380.woff2} +0 -0
  81. /package/lib/{iconfont.1756272539382.ttf → iconfont.1756629700380.ttf} +0 -0
  82. /package/lib/{iconfont.1756272539382.woff → iconfont.1756629700380.woff} +0 -0
  83. /package/lib/{iconfont.1756272539382.woff2 → iconfont.1756629700380.woff2} +0 -0
@@ -10,13 +10,15 @@ export default {
10
10
  * 关闭快捷菜单
11
11
  */
12
12
  _closeMenu() {
13
- Object.assign(this.ctxMenuStore, {
13
+ const $xeTable = this;
14
+ const reactData = $xeTable;
15
+ Object.assign(reactData.ctxMenuStore, {
14
16
  visible: false,
15
17
  selected: null,
16
18
  selectChild: null,
17
19
  showChild: false
18
20
  });
19
- return this.$nextTick();
21
+ return $xeTable.$nextTick();
20
22
  },
21
23
  // 处理菜单的移动
22
24
  moveCtxMenu(evnt, ctxMenuStore, property, hasOper, operRest, menuList) {
@@ -61,26 +63,35 @@ export default {
61
63
  const $xeTable = this;
62
64
  const $xeGrid = $xeTable.$xeGrid;
63
65
  const $xeGantt = $xeTable.$xeGantt;
66
+ const props = $xeTable;
67
+ const reactData = $xeTable;
64
68
  const internalData = $xeTable;
65
- const { $refs, tId, editStore, menuConfig, contextMenu, ctxMenuStore, ctxMenuOpts, mouseConfig, mouseOpts } = this;
66
- const { selected } = editStore;
69
+ const { xID } = $xeTable;
70
+ const { mouseConfig, menuConfig } = props;
71
+ const { editStore, ctxMenuStore } = reactData;
72
+ const { visibleColumn } = internalData;
67
73
  const tableFilter = $xeTable.$refs.refTableFilter;
74
+ const tableMenu = $xeTable.$refs.refTableMenu;
75
+ const mouseOpts = $xeTable.computeMouseOpts;
76
+ const menuOpts = $xeTable.computeMenuOpts;
77
+ const el = $xeTable.$refs.refElem;
78
+ const { selected } = editStore;
68
79
  const layoutList = ['header', 'body', 'footer'];
69
- if (isEnableConf(menuConfig) || contextMenu) {
70
- if (ctxMenuStore.visible && $refs.refTableMenu && getEventTargetNode(evnt, $refs.refTableMenu.$el).flag) {
80
+ if (isEnableConf(menuConfig)) {
81
+ if (ctxMenuStore.visible && tableMenu && getEventTargetNode(evnt, tableMenu.$el).flag) {
71
82
  evnt.preventDefault();
72
83
  return;
73
84
  }
74
85
  if (internalData._keyCtx) {
75
86
  const type = 'body';
76
- const params = { type, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, keyboard: true, columns: this.visibleColumn.slice(0), $event: evnt };
87
+ const params = { type, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, keyboard: true, columns: visibleColumn.slice(0), $event: evnt };
77
88
  // 如果开启单元格区域
78
89
  if (mouseConfig && mouseOpts.area) {
79
- const activeArea = this.getActiveCellArea();
90
+ const activeArea = $xeTable.getActiveCellArea();
80
91
  if (activeArea && activeArea.row && activeArea.column) {
81
92
  params.row = activeArea.row;
82
93
  params.column = activeArea.column;
83
- this.handleOpenMenuEvent(evnt, type, params);
94
+ $xeTable.handleOpenMenuEvent(evnt, type, params);
84
95
  return;
85
96
  }
86
97
  }
@@ -89,7 +100,7 @@ export default {
89
100
  if (selected.row && selected.column) {
90
101
  params.row = selected.row;
91
102
  params.column = selected.column;
92
- this.handleOpenMenuEvent(evnt, type, params);
103
+ $xeTable.handleOpenMenuEvent(evnt, type, params);
93
104
  return;
94
105
  }
95
106
  }
@@ -97,11 +108,11 @@ export default {
97
108
  // 分别匹配表尾、内容、表尾的快捷菜单
98
109
  for (let index = 0; index < layoutList.length; index++) {
99
110
  const layout = layoutList[index];
100
- const columnTargetNode = getEventTargetNode(evnt, this.$el, `vxe-${layout}--column`, (target) => {
111
+ const columnTargetNode = getEventTargetNode(evnt, el, `vxe-${layout}--column`, (target) => {
101
112
  // target=td|th,直接向上找 table 去匹配即可
102
- return target.parentNode.parentNode.parentNode.getAttribute('xid') === tId;
113
+ return target.parentNode.parentNode.parentNode.getAttribute('xid') === xID;
103
114
  });
104
- const params = { type: layout, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, columns: this.visibleColumn.slice(0), $event: evnt };
115
+ const params = { type: layout, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, columns: visibleColumn.slice(0), $event: evnt };
105
116
  if (columnTargetNode.flag) {
106
117
  const cell = columnTargetNode.targetElem;
107
118
  const columnNodeRest = $xeTable.getColumnNode(cell);
@@ -120,9 +131,9 @@ export default {
120
131
  }
121
132
  }
122
133
  const eventType = `${typePrefix}cell-menu`;
123
- this.handleOpenMenuEvent(evnt, layout, params);
134
+ $xeTable.handleOpenMenuEvent(evnt, layout, params);
124
135
  // 在 v4 中废弃事件 cell-context-menu、header-cell-context-menu、footer-cell-context-menu
125
- if (this.$listeners[`${typePrefix}cell-context-menu`]) {
136
+ if ($xeTable.$listeners[`${typePrefix}cell-context-menu`]) {
126
137
  warnLog('vxe.error.delEvent', [`${typePrefix}cell-context-menu`, `${typePrefix}cell-menu`]);
127
138
  $xeTable.dispatchEvent(`${typePrefix}cell-context-menu`, params, evnt);
128
139
  }
@@ -131,59 +142,65 @@ export default {
131
142
  }
132
143
  return;
133
144
  }
134
- else if (getEventTargetNode(evnt, this.$el, `vxe-table--${layout}-wrapper`, target => target.getAttribute('xid') === tId).flag) {
135
- if (ctxMenuOpts.trigger === 'cell') {
145
+ else if (getEventTargetNode(evnt, $xeTable.$el, `vxe-table--${layout}-wrapper`, target => target.getAttribute('xid') === xID).flag) {
146
+ if (menuOpts.trigger === 'cell') {
136
147
  evnt.preventDefault();
137
148
  }
138
149
  else {
139
- this.handleOpenMenuEvent(evnt, layout, params);
150
+ $xeTable.handleOpenMenuEvent(evnt, layout, params);
140
151
  }
141
152
  return;
142
153
  }
143
154
  }
144
155
  }
145
156
  if (tableFilter && !getEventTargetNode(evnt, tableFilter.$el).flag) {
146
- this.closeFilter();
157
+ $xeTable.closeFilter();
147
158
  }
148
- this.closeMenu();
159
+ $xeTable.closeMenu();
149
160
  },
150
161
  /**
151
162
  * 显示快捷菜单
152
163
  */
153
164
  handleOpenMenuEvent(evnt, type, params) {
154
- const { isCtxMenu, ctxMenuStore, ctxMenuOpts } = this;
155
- const config = ctxMenuOpts[type];
156
- const visibleMethod = ctxMenuOpts.visibleMethod;
165
+ const $xeTable = this;
166
+ const reactData = $xeTable;
167
+ const internalData = $xeTable;
168
+ const { ctxMenuStore } = reactData;
169
+ const isMenu = $xeTable.computeIsMenu;
170
+ const menuOpts = $xeTable.computeMenuOpts;
171
+ const config = menuOpts[type];
172
+ const visibleMethod = menuOpts.visibleMethod;
157
173
  if (config) {
158
174
  const { options, disabled } = config;
159
175
  if (disabled) {
160
176
  evnt.preventDefault();
161
177
  }
162
- else if (isCtxMenu && options && options.length) {
178
+ else if (isMenu && options && options.length) {
163
179
  params.options = options;
164
- this.preventEvent(evnt, 'event.showMenu', params, () => {
180
+ $xeTable.preventEvent(evnt, 'event.showMenu', params, () => {
165
181
  if (!visibleMethod || visibleMethod(params)) {
166
182
  evnt.preventDefault();
167
- this.updateZindex();
183
+ $xeTable.updateZindex();
168
184
  const { scrollTop, scrollLeft, visibleHeight, visibleWidth } = getDomNode();
169
185
  let top = evnt.clientY + scrollTop;
170
186
  let left = evnt.clientX + scrollLeft;
171
187
  const handleVisible = () => {
188
+ internalData._currMenuParams = params;
172
189
  Object.assign(ctxMenuStore, {
173
- args: params,
174
190
  visible: true,
175
191
  list: options,
176
192
  selected: null,
177
193
  selectChild: null,
178
194
  showChild: false,
179
195
  style: {
180
- zIndex: this.tZindex,
196
+ zIndex: internalData.tZindex,
181
197
  top: `${top}px`,
182
198
  left: `${left}px`
183
199
  }
184
200
  });
185
- this.$nextTick(() => {
186
- const ctxElem = this.$refs.refTableMenu.$el;
201
+ $xeTable.$nextTick(() => {
202
+ const tableMenu = $xeTable.$refs.refTableMenu;
203
+ const ctxElem = tableMenu.$el;
187
204
  const clientHeight = ctxElem.clientHeight;
188
205
  const clientWidth = ctxElem.clientWidth;
189
206
  const { boundingTop, boundingLeft } = getAbsolutePos(ctxElem);
@@ -199,11 +216,13 @@ export default {
199
216
  };
200
217
  const { keyboard, row, column } = params;
201
218
  if (keyboard && row && column) {
202
- this.scrollToRow(row, column).then(() => {
203
- const cell = this.getCellElement(row, column);
204
- const { boundingTop, boundingLeft } = getAbsolutePos(cell);
205
- top = boundingTop + scrollTop + Math.floor(cell.offsetHeight / 2);
206
- left = boundingLeft + scrollLeft + Math.floor(cell.offsetWidth / 2);
219
+ $xeTable.scrollToRow(row, column).then(() => {
220
+ const cell = $xeTable.getCellElement(row, column);
221
+ if (cell) {
222
+ const { boundingTop, boundingLeft } = getAbsolutePos(cell);
223
+ top = boundingTop + scrollTop + Math.floor(cell.offsetHeight / 2);
224
+ left = boundingLeft + scrollLeft + Math.floor(cell.offsetWidth / 2);
225
+ }
207
226
  handleVisible();
208
227
  });
209
228
  }
@@ -212,16 +231,18 @@ export default {
212
231
  }
213
232
  }
214
233
  else {
215
- this.closeMenu();
234
+ $xeTable.closeMenu();
216
235
  }
217
236
  });
218
237
  }
219
238
  }
220
- this.closeFilter();
239
+ $xeTable.closeFilter();
221
240
  },
222
241
  ctxMenuMouseoverEvent(evnt, item, child) {
242
+ const $xeTable = this;
243
+ const reactData = $xeTable;
223
244
  const menuElem = evnt.currentTarget;
224
- const ctxMenuStore = this.ctxMenuStore;
245
+ const { ctxMenuStore } = reactData;
225
246
  evnt.preventDefault();
226
247
  evnt.stopPropagation();
227
248
  ctxMenuStore.selected = item;
@@ -229,7 +250,7 @@ export default {
229
250
  if (!child) {
230
251
  ctxMenuStore.showChild = hasChildrenList(item);
231
252
  if (ctxMenuStore.showChild) {
232
- this.$nextTick(() => {
253
+ $xeTable.$nextTick(() => {
233
254
  const childWrapperElem = menuElem.nextElementSibling;
234
255
  if (childWrapperElem) {
235
256
  const { boundingTop, boundingLeft, visibleHeight, visibleWidth } = getAbsolutePos(menuElem);
@@ -259,7 +280,9 @@ export default {
259
280
  }
260
281
  },
261
282
  ctxMenuMouseoutEvent(evnt, item) {
262
- const ctxMenuStore = this.ctxMenuStore;
283
+ const $xeTable = this;
284
+ const reactData = $xeTable;
285
+ const { ctxMenuStore } = reactData;
263
286
  if (!item.children) {
264
287
  ctxMenuStore.selected = null;
265
288
  }
@@ -272,22 +295,23 @@ export default {
272
295
  const $xeTable = this;
273
296
  const $xeGrid = $xeTable.$xeGrid;
274
297
  const $xeGantt = $xeTable.$xeGantt;
298
+ const internalData = $xeTable;
275
299
  // 如果一级菜单有配置 code 则允许点击,否则不能点击
276
300
  if (!menu.disabled && (menu.code || !menu.children || !menu.children.length)) {
277
301
  const gMenuOpts = menus.get(menu.code);
278
- const params = Object.assign({ menu, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, $event: evnt }, this.ctxMenuStore.args);
302
+ const params = Object.assign({}, internalData._currMenuParams, { menu, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt, $event: evnt });
279
303
  if (gMenuOpts && gMenuOpts.menuMethod) {
280
304
  gMenuOpts.menuMethod(params, evnt);
281
305
  }
282
306
  // 在 v4 中废弃事件 context-menu-click
283
- if (this.$listeners['context-menu-click']) {
307
+ if ($xeTable.$listeners['context-menu-click']) {
284
308
  warnLog('vxe.error.delEvent', ['context-menu-click', 'menu-click']);
285
309
  $xeTable.dispatchEvent('context-menu-click', params, evnt);
286
310
  }
287
311
  else {
288
312
  $xeTable.dispatchEvent('menu-click', params, evnt);
289
313
  }
290
- this.closeMenu();
314
+ $xeTable.closeMenu();
291
315
  }
292
316
  }
293
317
  }
@@ -1,6 +1,6 @@
1
1
  import { VxeUI } from '../../../ui';
2
2
  import { getFuncText } from '../../../ui/src/utils';
3
- const { getIcon } = VxeUI;
3
+ const { getIcon, renderEmptyElement } = VxeUI;
4
4
  export default {
5
5
  name: 'VxeTableMenuPanel',
6
6
  props: {
@@ -18,15 +18,17 @@ export default {
18
18
  },
19
19
  render(h) {
20
20
  const $xeTable = this.$parent;
21
- const { _e, ctxMenuOpts, ctxMenuStore } = this;
21
+ const tableReactData = $xeTable;
22
+ const { ctxMenuStore } = tableReactData;
23
+ const menuOpts = $xeTable.computeMenuOpts;
22
24
  return h('div', {
23
- class: ['vxe-table--context-menu-wrapper', ctxMenuOpts.className, {
25
+ class: ['vxe-table--context-menu-wrapper', menuOpts.className, {
24
26
  'is--visible': ctxMenuStore.visible
25
27
  }],
26
28
  style: ctxMenuStore.style
27
29
  }, ctxMenuStore.list.map((options, gIndex) => {
28
30
  return options.every((item) => item.visible === false)
29
- ? _e()
31
+ ? renderEmptyElement($xeTable)
30
32
  : h('ul', {
31
33
  class: 'vxe-context-menu--option-wrapper',
32
34
  key: gIndex
@@ -64,7 +66,7 @@ export default {
64
66
  h('i', {
65
67
  class: prefixOpts.icon || item.prefixIcon
66
68
  }),
67
- prefixOpts.content ? h('span', {}, `${prefixOpts.content}`) : _e()
69
+ prefixOpts.content ? h('span', {}, `${prefixOpts.content}`) : renderEmptyElement($xeTable)
68
70
  ]),
69
71
  h('span', {
70
72
  class: 'vxe-context-menu--link-content',
@@ -78,7 +80,7 @@ export default {
78
80
  h('i', {
79
81
  class: (suffixOpts.icon || item.suffixIcon) || (hasChildMenus ? getIcon().TABLE_MENU_OPTIONS : '')
80
82
  }),
81
- suffixOpts.content ? h('span', `${suffixOpts.content}`) : _e()
83
+ suffixOpts.content ? h('span', `${suffixOpts.content}`) : renderEmptyElement($xeTable)
82
84
  ])
83
85
  ]),
84
86
  hasChildMenus
@@ -119,7 +121,7 @@ export default {
119
121
  h('i', {
120
122
  class: childPrefixOpts.icon || child.prefixIcon
121
123
  }),
122
- childPrefixOpts.content ? h('span', `${childPrefixOpts.content}`) : _e()
124
+ childPrefixOpts.content ? h('span', `${childPrefixOpts.content}`) : renderEmptyElement($xeTable)
123
125
  ]),
124
126
  h('span', {
125
127
  class: 'vxe-context-menu--link-content',
@@ -133,7 +135,7 @@ export default {
133
135
  h('i', {
134
136
  class: childSuffixOpts.icon
135
137
  }),
136
- childSuffixOpts.content ? h('span', `${childSuffixOpts.content}`) : _e()
138
+ childSuffixOpts.content ? h('span', `${childSuffixOpts.content}`) : renderEmptyElement($xeTable)
137
139
  ])
138
140
  ])
139
141
  ]);
@@ -148,15 +148,14 @@ function renderTdColumn(h, $xeTable, seq, rowid, fixedType, isOptimizeMode, rowL
148
148
  // hover 进入事件
149
149
  if (showTitle || showTooltip || showAllTip || tooltipConfig) {
150
150
  tdOns.mouseenter = (evnt) => {
151
- if (isVMScrollProcess($xeTable)) {
152
- return;
153
- }
154
- if (showTitle) {
155
- updateCellTitle(evnt.currentTarget, column);
156
- }
157
- else if (showTooltip || showAllTip) {
158
- // 如果配置了显示 tooltip
159
- $xeTable.triggerBodyTooltipEvent(evnt, cellParams);
151
+ if (!isVMScrollProcess($xeTable)) {
152
+ if (showTitle) {
153
+ updateCellTitle(evnt.currentTarget, column);
154
+ }
155
+ else if (showTooltip || showAllTip) {
156
+ // 如果配置了显示 tooltip
157
+ $xeTable.triggerBodyTooltipEvent(evnt, cellParams);
158
+ }
160
159
  }
161
160
  $xeTable.dispatchEvent('cell-mouseenter', Object.assign({ cell: evnt.currentTarget }, cellParams), evnt);
162
161
  };
@@ -164,11 +163,10 @@ function renderTdColumn(h, $xeTable, seq, rowid, fixedType, isOptimizeMode, rowL
164
163
  // hover 退出事件
165
164
  if (showTooltip || showAllTip || tooltipConfig) {
166
165
  tdOns.mouseleave = (evnt) => {
167
- if (isVMScrollProcess($xeTable)) {
168
- return;
169
- }
170
- if (showTooltip || showAllTip) {
171
- $xeTable.handleTargetLeaveEvent(evnt);
166
+ if (!isVMScrollProcess($xeTable)) {
167
+ if (showTooltip || showAllTip) {
168
+ $xeTable.handleTargetLeaveEvent(evnt);
169
+ }
172
170
  }
173
171
  $xeTable.dispatchEvent('cell-mouseleave', Object.assign({ cell: evnt.currentTarget }, cellParams), evnt);
174
172
  };
@@ -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
  };