vxe-table 3.15.5 → 3.15.7

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 (171) hide show
  1. package/es/index.css +1 -1
  2. package/es/index.min.css +1 -1
  3. package/es/locale/lang/ar-EG.js +3 -2
  4. package/es/locale/lang/de-DE.js +3 -2
  5. package/es/locale/lang/en-US.js +2 -1
  6. package/es/locale/lang/es-ES.js +3 -2
  7. package/es/locale/lang/fr-FR.js +2 -1
  8. package/es/locale/lang/hu-HU.js +2 -1
  9. package/es/locale/lang/hy-AM.js +2 -1
  10. package/es/locale/lang/id-ID.js +2 -1
  11. package/es/locale/lang/it-IT.js +2 -1
  12. package/es/locale/lang/ja-JP.js +2 -1
  13. package/es/locale/lang/ko-KR.js +2 -1
  14. package/es/locale/lang/nb-NO.js +2 -1
  15. package/es/locale/lang/pt-BR.js +2 -1
  16. package/es/locale/lang/ru-RU.js +2 -1
  17. package/es/locale/lang/th-TH.js +2 -1
  18. package/es/locale/lang/ug-CN.js +2 -1
  19. package/es/locale/lang/uk-UA.js +2 -1
  20. package/es/locale/lang/vi-VN.js +2 -1
  21. package/es/locale/lang/zh-CHT.js +2 -1
  22. package/es/locale/lang/zh-CN.js +2 -1
  23. package/es/style.css +1 -1
  24. package/es/style.min.css +1 -1
  25. package/es/table/module/custom/mixin.js +62 -37
  26. package/es/table/module/custom/panel.js +7 -7
  27. package/es/table/module/export/mixin.js +13 -12
  28. package/es/table/module/keyboard/mixin.js +3 -2
  29. package/es/table/src/body.js +49 -16
  30. package/es/table/src/cell.js +137 -45
  31. package/es/table/src/column.js +2 -0
  32. package/es/table/src/columnInfo.js +1 -0
  33. package/es/table/src/methods.js +983 -495
  34. package/es/table/src/props.js +9 -7
  35. package/es/table/src/table.js +108 -35
  36. package/es/table/style.css +70 -40
  37. package/es/table/style.min.css +1 -1
  38. package/es/ui/index.js +13 -1
  39. package/es/ui/src/dom.js +3 -0
  40. package/es/ui/src/log.js +1 -1
  41. package/es/vxe-table/style.css +70 -40
  42. package/es/vxe-table/style.min.css +1 -1
  43. package/lib/index.css +1 -1
  44. package/lib/index.min.css +1 -1
  45. package/lib/index.umd.js +1735 -858
  46. package/lib/index.umd.min.js +1 -1
  47. package/lib/locale/lang/ar-EG.js +3 -2
  48. package/lib/locale/lang/ar-EG.min.js +1 -1
  49. package/lib/locale/lang/de-DE.js +3 -2
  50. package/lib/locale/lang/de-DE.min.js +1 -1
  51. package/lib/locale/lang/en-US.js +2 -1
  52. package/lib/locale/lang/en-US.min.js +1 -1
  53. package/lib/locale/lang/en-US.umd.js +2 -1
  54. package/lib/locale/lang/es-ES.js +3 -2
  55. package/lib/locale/lang/es-ES.min.js +1 -1
  56. package/lib/locale/lang/es-ES.umd.js +3 -2
  57. package/lib/locale/lang/fr-FR.js +2 -1
  58. package/lib/locale/lang/fr-FR.min.js +1 -1
  59. package/lib/locale/lang/hu-HU.js +2 -1
  60. package/lib/locale/lang/hu-HU.min.js +1 -1
  61. package/lib/locale/lang/hu-HU.umd.js +2 -1
  62. package/lib/locale/lang/hy-AM.js +2 -1
  63. package/lib/locale/lang/hy-AM.min.js +1 -1
  64. package/lib/locale/lang/id-ID.js +2 -1
  65. package/lib/locale/lang/id-ID.min.js +1 -1
  66. package/lib/locale/lang/it-IT.js +2 -1
  67. package/lib/locale/lang/it-IT.min.js +1 -1
  68. package/lib/locale/lang/ja-JP.js +2 -1
  69. package/lib/locale/lang/ja-JP.min.js +1 -1
  70. package/lib/locale/lang/ja-JP.umd.js +2 -1
  71. package/lib/locale/lang/ko-KR.js +2 -1
  72. package/lib/locale/lang/ko-KR.min.js +1 -1
  73. package/lib/locale/lang/ko-KR.umd.js +2 -1
  74. package/lib/locale/lang/nb-NO.js +2 -1
  75. package/lib/locale/lang/nb-NO.min.js +1 -1
  76. package/lib/locale/lang/pt-BR.js +2 -1
  77. package/lib/locale/lang/pt-BR.min.js +1 -1
  78. package/lib/locale/lang/pt-BR.umd.js +2 -1
  79. package/lib/locale/lang/ru-RU.js +2 -1
  80. package/lib/locale/lang/ru-RU.min.js +1 -1
  81. package/lib/locale/lang/ru-RU.umd.js +2 -1
  82. package/lib/locale/lang/th-TH.js +2 -1
  83. package/lib/locale/lang/th-TH.min.js +1 -1
  84. package/lib/locale/lang/ug-CN.js +2 -1
  85. package/lib/locale/lang/ug-CN.min.js +1 -1
  86. package/lib/locale/lang/uk-UA.js +2 -1
  87. package/lib/locale/lang/uk-UA.min.js +1 -1
  88. package/lib/locale/lang/uk-UA.umd.js +2 -1
  89. package/lib/locale/lang/vi-VN.js +2 -1
  90. package/lib/locale/lang/vi-VN.min.js +1 -1
  91. package/lib/locale/lang/zh-CHT.js +2 -1
  92. package/lib/locale/lang/zh-CHT.min.js +1 -1
  93. package/lib/locale/lang/zh-CHT.umd.js +2 -1
  94. package/lib/locale/lang/zh-CN.js +2 -1
  95. package/lib/locale/lang/zh-CN.min.js +1 -1
  96. package/lib/locale/lang/zh-CN.umd.js +2 -1
  97. package/lib/style.css +1 -1
  98. package/lib/style.min.css +1 -1
  99. package/lib/table/module/custom/mixin.js +74 -48
  100. package/lib/table/module/custom/mixin.min.js +1 -1
  101. package/lib/table/module/custom/panel.js +6 -2
  102. package/lib/table/module/custom/panel.min.js +1 -1
  103. package/lib/table/module/export/mixin.js +13 -5
  104. package/lib/table/module/export/mixin.min.js +1 -1
  105. package/lib/table/module/keyboard/mixin.js +2 -1
  106. package/lib/table/module/keyboard/mixin.min.js +1 -1
  107. package/lib/table/src/body.js +39 -15
  108. package/lib/table/src/body.min.js +1 -1
  109. package/lib/table/src/cell.js +157 -36
  110. package/lib/table/src/cell.min.js +1 -1
  111. package/lib/table/src/column.js +2 -0
  112. package/lib/table/src/column.min.js +1 -1
  113. package/lib/table/src/columnInfo.js +1 -0
  114. package/lib/table/src/columnInfo.min.js +1 -1
  115. package/lib/table/src/methods.js +1164 -562
  116. package/lib/table/src/methods.min.js +1 -1
  117. package/lib/table/src/props.js +9 -7
  118. package/lib/table/src/props.min.js +1 -1
  119. package/lib/table/src/table.js +104 -34
  120. package/lib/table/src/table.min.js +1 -1
  121. package/lib/table/style/style.css +70 -40
  122. package/lib/table/style/style.min.css +1 -1
  123. package/lib/ui/index.js +13 -1
  124. package/lib/ui/index.min.js +1 -1
  125. package/lib/ui/src/dom.js +4 -0
  126. package/lib/ui/src/dom.min.js +1 -1
  127. package/lib/ui/src/log.js +1 -1
  128. package/lib/ui/src/log.min.js +1 -1
  129. package/lib/vxe-table/style/style.css +70 -40
  130. package/lib/vxe-table/style/style.min.css +1 -1
  131. package/package.json +2 -2
  132. package/packages/locale/lang/ar-EG.ts +3 -2
  133. package/packages/locale/lang/de-DE.ts +3 -2
  134. package/packages/locale/lang/en-US.ts +2 -1
  135. package/packages/locale/lang/es-ES.ts +3 -2
  136. package/packages/locale/lang/fr-FR.ts +2 -1
  137. package/packages/locale/lang/hu-HU.ts +2 -1
  138. package/packages/locale/lang/hy-AM.ts +2 -1
  139. package/packages/locale/lang/id-ID.ts +2 -1
  140. package/packages/locale/lang/it-IT.ts +2 -1
  141. package/packages/locale/lang/ja-JP.ts +2 -1
  142. package/packages/locale/lang/ko-KR.ts +2 -1
  143. package/packages/locale/lang/nb-NO.ts +2 -1
  144. package/packages/locale/lang/pt-BR.ts +2 -1
  145. package/packages/locale/lang/ru-RU.ts +2 -1
  146. package/packages/locale/lang/th-TH.ts +2 -1
  147. package/packages/locale/lang/ug-CN.ts +2 -1
  148. package/packages/locale/lang/uk-UA.ts +2 -1
  149. package/packages/locale/lang/vi-VN.ts +2 -1
  150. package/packages/locale/lang/zh-CHT.ts +2 -1
  151. package/packages/locale/lang/zh-CN.ts +2 -1
  152. package/packages/table/module/custom/mixin.ts +85 -51
  153. package/packages/table/module/custom/panel.ts +8 -8
  154. package/packages/table/module/export/mixin.ts +19 -18
  155. package/packages/table/module/keyboard/mixin.ts +3 -2
  156. package/packages/table/src/body.ts +50 -17
  157. package/packages/table/src/cell.ts +136 -45
  158. package/packages/table/src/column.ts +2 -0
  159. package/packages/table/src/columnInfo.ts +1 -0
  160. package/packages/table/src/methods.ts +1016 -512
  161. package/packages/table/src/props.ts +9 -7
  162. package/packages/table/src/table.ts +122 -38
  163. package/packages/ui/index.ts +12 -0
  164. package/packages/ui/src/dom.ts +4 -0
  165. package/styles/components/table.scss +131 -92
  166. /package/es/{iconfont.1744880837792.ttf → iconfont.1745290222894.ttf} +0 -0
  167. /package/es/{iconfont.1744880837792.woff → iconfont.1745290222894.woff} +0 -0
  168. /package/es/{iconfont.1744880837792.woff2 → iconfont.1745290222894.woff2} +0 -0
  169. /package/lib/{iconfont.1744880837792.ttf → iconfont.1745290222894.ttf} +0 -0
  170. /package/lib/{iconfont.1744880837792.woff → iconfont.1745290222894.woff} +0 -0
  171. /package/lib/{iconfont.1744880837792.woff2 → iconfont.1745290222894.woff2} +0 -0
@@ -1,5 +1,5 @@
1
1
  import XEUtils from 'xe-utils';
2
- import { getTpImg, isPx, isScale, hasClass, addClass, removeClass, getEventTargetNode, getPaddingTopBottomSize, getOffsetPos, setScrollTop, setScrollLeft, toCssUnit } from '../../ui/src/dom';
2
+ import { getTpImg, isPx, isScale, hasClass, addClass, removeClass, getEventTargetNode, getPaddingTopBottomSize, getOffsetPos, setScrollTop, setScrollLeft, toCssUnit, hasControlKey } from '../../ui/src/dom';
3
3
  import { getLastZIndex, nextZIndex, hasChildrenList, getFuncText, isEnableConf, formatText, eqEmptyValue } from '../../ui/src/utils';
4
4
  import { VxeUI } from '../../ui';
5
5
  import Cell from './cell';
@@ -170,7 +170,7 @@ function restoreCustomStorage($xeTable) {
170
170
  }
171
171
  const storeData = getCustomStorageMap(tableId);
172
172
  if (restoreStore) {
173
- return Promise.resolve(restoreStore({ id: tableId, type: 'restore', storeData })).then(storeData => {
173
+ return Promise.resolve(restoreStore({ $table: $xeTable, id: tableId, type: 'restore', storeData })).then(storeData => {
174
174
  if (!storeData) {
175
175
  return;
176
176
  }
@@ -203,6 +203,7 @@ function cacheColumnMap($xeTable) {
203
203
  const rowOpts = $xeTable.computeRowOpts;
204
204
  const isGroup = collectColumn.some(hasChildrenList);
205
205
  let isAllOverflow = !!props.showOverflow;
206
+ let rowGroupColumn;
206
207
  let expandColumn;
207
208
  let treeNodeColumn;
208
209
  let checkboxColumn;
@@ -210,7 +211,7 @@ function cacheColumnMap($xeTable) {
210
211
  let htmlColumn;
211
212
  let hasFixed;
212
213
  const handleFunc = (column, index, items, path, parentColumn) => {
213
- const { id: colid, field, fixed, type, treeNode } = column;
214
+ const { id: colid, field, fixed, type, treeNode, rowGroupNode } = column;
214
215
  const rest = { $index: -1, _index: -1, column, colid, index, items, parent: parentColumn || null, width: 0, oLeft: 0 };
215
216
  if (field) {
216
217
  if (fullColumnFieldData[field]) {
@@ -237,7 +238,15 @@ function cacheColumnMap($xeTable) {
237
238
  treeNodeColumn = column;
238
239
  }
239
240
  }
240
- else if (type === 'expand') {
241
+ if (rowGroupNode) {
242
+ if (treeNodeColumn) {
243
+ warnLog('vxe.error.colRepet', ['row-group-node', rowGroupNode]);
244
+ }
245
+ if (!rowGroupColumn) {
246
+ rowGroupColumn = column;
247
+ }
248
+ }
249
+ if (type === 'expand') {
241
250
  if (expandColumn) {
242
251
  warnLog('vxe.error.colRepet', ['type', type]);
243
252
  }
@@ -290,6 +299,7 @@ function cacheColumnMap($xeTable) {
290
299
  }
291
300
  }
292
301
  reactData.isGroup = isGroup;
302
+ reactData.rowGroupColumn = rowGroupColumn;
293
303
  reactData.treeNodeColumn = treeNodeColumn;
294
304
  reactData.expandColumn = expandColumn;
295
305
  reactData.isAllOverflow = isAllOverflow;
@@ -318,7 +328,7 @@ function handleBaseTreeExpand($xeTable, rows, expanded) {
318
328
  const reactData = $xeTable;
319
329
  const internalData = $xeTable;
320
330
  const { treeNodeColumn } = reactData;
321
- const { fullAllDataRowIdData, tableFullData, treeExpandedMaps, treeExpandLazyLoadedMaps } = internalData;
331
+ const { fullAllDataRowIdData, tableFullTreeData, treeExpandedMaps, treeExpandLazyLoadedMaps } = internalData;
322
332
  const treeOpts = $xeTable.computeTreeOpts;
323
333
  const { reserve, lazy, accordion, toggleMethod } = treeOpts;
324
334
  const childrenField = treeOpts.children || treeOpts.childrenField;
@@ -331,7 +341,7 @@ function handleBaseTreeExpand($xeTable, rows, expanded) {
331
341
  if (accordion) {
332
342
  validRows = validRows.length ? [validRows[validRows.length - 1]] : [];
333
343
  // 同一级只能展开一个
334
- const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], { children: childrenField });
344
+ const matchObj = XEUtils.findTree(tableFullTreeData, item => item === validRows[0], { children: childrenField });
335
345
  if (matchObj) {
336
346
  matchObj.items.forEach(item => {
337
347
  const rowid = handleGetRowId(item);
@@ -384,9 +394,86 @@ function handleBaseTreeExpand($xeTable, rows, expanded) {
384
394
  * @returns
385
395
  */
386
396
  function handleVirtualTreeExpand($xeTable, rows, expanded) {
397
+ const reactData = $xeTable;
387
398
  return handleBaseTreeExpand($xeTable, rows, expanded).then(() => {
388
399
  handleVirtualTreeToList($xeTable);
389
400
  $xeTable.handleTableData();
401
+ reactData.treeExpandedFlag++;
402
+ updateAfterDataIndex($xeTable);
403
+ return $xeTable.$nextTick();
404
+ }).then(() => {
405
+ return $xeTable.recalculate(true);
406
+ }).then(() => {
407
+ setTimeout(() => {
408
+ $xeTable.updateCellAreas();
409
+ }, 30);
410
+ });
411
+ }
412
+ /**
413
+ * 展开与收起行分组节点
414
+ * @param rows
415
+ * @param expanded
416
+ * @returns
417
+ */
418
+ function handleRowGroupBaseExpand($xeTable, rows, expanded) {
419
+ const reactData = $xeTable;
420
+ const internalData = $xeTable;
421
+ const { fullAllDataRowIdData, tableFullGroupData, rowGroupExpandedMaps } = internalData;
422
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
423
+ const { mapChildrenField, accordion } = rowGroupOpts;
424
+ const { handleGetRowId } = createHandleGetRowId($xeTable);
425
+ let validRows = rows;
426
+ if (mapChildrenField) {
427
+ if (accordion) {
428
+ validRows = validRows.length ? [validRows[validRows.length - 1]] : [];
429
+ // 同一级只能展开一个
430
+ const matchObj = XEUtils.findTree(tableFullGroupData, item => getRowid($xeTable, item) === getRowid($xeTable, validRows[0]), { children: mapChildrenField });
431
+ if (matchObj) {
432
+ matchObj.items.forEach(item => {
433
+ const rowid = handleGetRowId(item);
434
+ if (rowGroupExpandedMaps[rowid]) {
435
+ delete rowGroupExpandedMaps[rowid];
436
+ }
437
+ });
438
+ }
439
+ }
440
+ if (expanded) {
441
+ validRows.forEach((row) => {
442
+ const rowid = handleGetRowId(row);
443
+ if (!rowGroupExpandedMaps[rowid]) {
444
+ const rowRest = fullAllDataRowIdData[rowid];
445
+ if (rowRest) {
446
+ if (row[mapChildrenField] && row[mapChildrenField].length) {
447
+ rowGroupExpandedMaps[rowid] = row;
448
+ }
449
+ }
450
+ }
451
+ });
452
+ }
453
+ else {
454
+ validRows.forEach(item => {
455
+ const rowid = handleGetRowId(item);
456
+ if (rowGroupExpandedMaps[rowid]) {
457
+ delete rowGroupExpandedMaps[rowid];
458
+ }
459
+ });
460
+ }
461
+ }
462
+ reactData.rowGroupExpandedFlag++;
463
+ return $xeTable.recalculate();
464
+ }
465
+ /**
466
+ * 行分组的展开与收起
467
+ * @param rows
468
+ * @param expanded
469
+ * @returns
470
+ */
471
+ function handleRowGroupVirtualExpand($xeTable, rows, expanded) {
472
+ const reactData = $xeTable;
473
+ return handleRowGroupBaseExpand($xeTable, rows, expanded).then(() => {
474
+ handleVirtualTreeToList($xeTable);
475
+ $xeTable.handleTableData();
476
+ reactData.rowGroupExpandedFlag++;
390
477
  updateAfterDataIndex($xeTable);
391
478
  return $xeTable.$nextTick();
392
479
  }).then(() => {
@@ -461,20 +548,23 @@ function updateAfterDataIndex($xeTable) {
461
548
  }
462
549
  }
463
550
  /**
464
- * 如果为虚拟树,将树结构拍平
551
+ * 如果为虚拟树、行分组、则将树结构拍平
465
552
  * @returns
466
553
  */
467
554
  function handleVirtualTreeToList($xeTable) {
468
555
  const props = $xeTable;
556
+ const reactData = $xeTable;
469
557
  const internalData = $xeTable;
470
558
  const { treeConfig } = props;
471
- const { fullAllDataRowIdData, treeExpandedMaps } = internalData;
559
+ const { isRowGroupStatus } = reactData;
560
+ const { fullAllDataRowIdData, treeExpandedMaps, rowGroupExpandedMaps } = internalData;
561
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
472
562
  const treeOpts = $xeTable.computeTreeOpts;
473
- const childrenField = treeOpts.children || treeOpts.childrenField;
563
+ const { handleGetRowId } = createHandleGetRowId($xeTable);
564
+ const fullData = [];
565
+ const expandMaps = {};
474
566
  if (treeConfig && treeOpts.transform) {
475
- const { handleGetRowId } = createHandleGetRowId($xeTable);
476
- const fullData = [];
477
- const expandMaps = {};
567
+ const childrenField = treeOpts.children || treeOpts.childrenField;
478
568
  XEUtils.eachTree(internalData.afterTreeFullData, (row, index, items, path, parentRow) => {
479
569
  const rowid = handleGetRowId(row);
480
570
  const parentRowid = handleGetRowId(parentRow);
@@ -491,8 +581,249 @@ function handleVirtualTreeToList($xeTable) {
491
581
  updateScrollYStatus($xeTable, fullData);
492
582
  return fullData;
493
583
  }
584
+ else if (isRowGroupStatus) {
585
+ const { childrenField } = rowGroupOpts;
586
+ XEUtils.eachTree(internalData.afterGroupFullData, (row, index, items, path, parentRow) => {
587
+ const rowid = handleGetRowId(row);
588
+ const parentRowid = handleGetRowId(parentRow);
589
+ if (!parentRow || (expandMaps[parentRowid] && rowGroupExpandedMaps[parentRowid])) {
590
+ const rowRest = fullAllDataRowIdData[rowid];
591
+ if (rowRest) {
592
+ rowRest._index = fullData.length;
593
+ }
594
+ expandMaps[rowid] = 1;
595
+ fullData.push(row);
596
+ }
597
+ }, { children: childrenField });
598
+ internalData.afterFullData = fullData;
599
+ updateScrollYStatus($xeTable, fullData);
600
+ return fullData;
601
+ }
494
602
  return internalData.afterFullData;
495
603
  }
604
+ /**
605
+ * 编译处理后全量的表格数据
606
+ * 如果存在筛选条件,继续处理
607
+ */
608
+ function updateAfterFullData($xeTable) {
609
+ const props = $xeTable;
610
+ const reactData = $xeTable;
611
+ const internalData = $xeTable;
612
+ const { treeConfig } = props;
613
+ const { isRowGroupStatus } = reactData;
614
+ const { tableFullColumn, tableFullData, tableFullTreeData, tableFullGroupData } = internalData;
615
+ const filterOpts = $xeTable.computeFilterOpts;
616
+ const sortOpts = $xeTable.computeSortOpts;
617
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
618
+ const treeOpts = $xeTable.computeTreeOpts;
619
+ const childrenField = treeOpts.children || treeOpts.childrenField;
620
+ const { transform, rowField, parentField, mapChildrenField } = treeOpts;
621
+ const { isEvery, remote: allRemoteFilter, filterMethod: allFilterMethod } = filterOpts;
622
+ const { remote: allRemoteSort, sortMethod: allSortMethod, multiple: sortMultiple, chronological } = sortOpts;
623
+ let tableData = [];
624
+ let tableTree = [];
625
+ // 处理数据
626
+ if (!allRemoteFilter || !allRemoteSort) {
627
+ const filterColumns = [];
628
+ let orderColumns = [];
629
+ tableFullColumn.forEach((column) => {
630
+ const { field, sortable, order, filters } = column;
631
+ if (!allRemoteFilter && filters && filters.length) {
632
+ const valueList = [];
633
+ const itemList = [];
634
+ filters.forEach((item) => {
635
+ if (item.checked) {
636
+ itemList.push(item);
637
+ valueList.push(item.value);
638
+ }
639
+ });
640
+ if (itemList.length) {
641
+ filterColumns.push({ column, valueList, itemList });
642
+ }
643
+ }
644
+ if (!allRemoteSort && sortable && order) {
645
+ orderColumns.push({ column, field, property: field, order: order, sortTime: column.sortTime });
646
+ }
647
+ });
648
+ if (sortMultiple && chronological && orderColumns.length > 1) {
649
+ orderColumns = XEUtils.orderBy(orderColumns, 'sortTime');
650
+ }
651
+ // 处理筛选
652
+ // 支持单列、多列、组合筛选
653
+ if (!allRemoteFilter && filterColumns.length) {
654
+ const handleFilter = (row) => {
655
+ return filterColumns.every(({ column, valueList, itemList }) => {
656
+ const { filterMethod, filterRender } = column;
657
+ const compConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null;
658
+ const compFilterMethod = compConf ? (compConf.tableFilterMethod || compConf.filterMethod) : null;
659
+ const tdFilterMethod = compConf ? (compConf.tableFilterDefaultMethod || compConf.defaultTableFilterMethod || compConf.defaultFilterMethod) : null;
660
+ const cellValue = getCellValue(row, column);
661
+ if (filterMethod) {
662
+ return itemList.some((item) => filterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
663
+ }
664
+ else if (compFilterMethod) {
665
+ return itemList.some((item) => compFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
666
+ }
667
+ else if (allFilterMethod) {
668
+ return allFilterMethod({ $table: $xeTable, options: itemList, values: valueList, cellValue, row, column });
669
+ }
670
+ else if (tdFilterMethod) {
671
+ return itemList.some((item) => tdFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
672
+ }
673
+ return valueList.indexOf(XEUtils.get(row, column.field)) > -1;
674
+ });
675
+ };
676
+ if (isRowGroupStatus) {
677
+ // 行分组
678
+ tableTree = XEUtils.searchTree(tableFullGroupData, handleFilter, {
679
+ original: true,
680
+ isEvery: true,
681
+ children: rowGroupOpts.mapChildrenField,
682
+ mapChildren: rowGroupOpts.childrenField
683
+ });
684
+ tableData = tableTree;
685
+ }
686
+ else if (treeConfig && transform) {
687
+ // 筛选虚拟树
688
+ tableTree = XEUtils.searchTree(tableFullTreeData, handleFilter, {
689
+ original: true,
690
+ isEvery,
691
+ children: mapChildrenField,
692
+ mapChildren: childrenField
693
+ });
694
+ tableData = tableTree;
695
+ }
696
+ else {
697
+ tableData = treeConfig ? tableFullTreeData.filter(handleFilter) : tableFullData.filter(handleFilter);
698
+ tableTree = tableData;
699
+ }
700
+ }
701
+ else {
702
+ if (isRowGroupStatus) {
703
+ // 还原行分组
704
+ tableTree = XEUtils.searchTree(tableFullGroupData, () => true, {
705
+ original: true,
706
+ isEvery: true,
707
+ children: rowGroupOpts.mapChildrenField,
708
+ mapChildren: rowGroupOpts.childrenField
709
+ });
710
+ tableData = tableTree;
711
+ }
712
+ else if (treeConfig && transform) {
713
+ // 还原虚拟树
714
+ tableTree = XEUtils.searchTree(tableFullTreeData, () => true, {
715
+ original: true,
716
+ isEvery,
717
+ children: mapChildrenField,
718
+ mapChildren: childrenField
719
+ });
720
+ tableData = tableTree;
721
+ }
722
+ else {
723
+ tableData = treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0);
724
+ tableTree = tableData;
725
+ }
726
+ }
727
+ // 处理排序
728
+ // 支持单列、多列、组合排序
729
+ if (!allRemoteSort && orderColumns.length) {
730
+ if (isRowGroupStatus) {
731
+ // 行分组的排序
732
+ if (allSortMethod) {
733
+ const sortRests = allSortMethod({ data: tableTree, sortList: orderColumns, $table: $xeTable });
734
+ tableTree = XEUtils.isArray(sortRests) ? sortRests : tableTree;
735
+ }
736
+ else {
737
+ const treeList = XEUtils.toTreeArray(tableTree, {
738
+ key: rowGroupOpts.rowField,
739
+ parentKey: rowGroupOpts.parentField,
740
+ children: rowGroupOpts.mapChildrenField
741
+ });
742
+ tableTree = XEUtils.toArrayTree(XEUtils.orderBy(treeList, orderColumns.map(({ column, order }) => [getOrderField($xeTable, column), order])), {
743
+ key: rowGroupOpts.rowField,
744
+ parentKey: rowGroupOpts.parentField,
745
+ children: rowGroupOpts.childrenField,
746
+ mapChildren: rowGroupOpts.mapChildrenField
747
+ });
748
+ }
749
+ tableData = tableTree;
750
+ }
751
+ else if (treeConfig && transform) {
752
+ // 虚拟树的排序
753
+ if (allSortMethod) {
754
+ const sortRests = allSortMethod({ data: tableTree, sortList: orderColumns, $table: $xeTable });
755
+ tableTree = XEUtils.isArray(sortRests) ? sortRests : tableTree;
756
+ }
757
+ else {
758
+ const treeList = XEUtils.toTreeArray(tableTree, {
759
+ children: mapChildrenField
760
+ });
761
+ tableTree = XEUtils.toArrayTree(XEUtils.orderBy(treeList, orderColumns.map(({ column, order }) => [getOrderField($xeTable, column), order])), {
762
+ key: rowField,
763
+ parentKey: parentField,
764
+ children: childrenField,
765
+ mapChildren: mapChildrenField
766
+ });
767
+ }
768
+ tableData = tableTree;
769
+ }
770
+ else {
771
+ if (allSortMethod) {
772
+ const sortRests = allSortMethod({ data: tableData, sortList: orderColumns, $table: $xeTable });
773
+ tableData = XEUtils.isArray(sortRests) ? sortRests : tableData;
774
+ }
775
+ else {
776
+ // 兼容 v4
777
+ if (sortMultiple) {
778
+ tableData = XEUtils.orderBy(tableData, orderColumns.map(({ column, order }) => [getOrderField($xeTable, column), order]));
779
+ }
780
+ else {
781
+ const firstOrderColumn = orderColumns[0];
782
+ let sortByConfs;
783
+ // 已废弃,兼容 v2,在 v4 中废弃, sortBy 不能为数组
784
+ if (XEUtils.isArray(firstOrderColumn.sortBy)) {
785
+ sortByConfs = firstOrderColumn.sortBy.map((item) => [item, firstOrderColumn.order]);
786
+ }
787
+ tableData = XEUtils.orderBy(tableData, sortByConfs || [firstOrderColumn].map(({ column, order }) => [getOrderField($xeTable, column), order]));
788
+ }
789
+ tableData = XEUtils.orderBy(tableData, orderColumns.map(({ column, order }) => [getOrderField($xeTable, column), order]));
790
+ }
791
+ tableTree = tableData;
792
+ }
793
+ }
794
+ }
795
+ else {
796
+ if (isRowGroupStatus) {
797
+ // 还原行分组
798
+ // 还原虚拟树
799
+ tableTree = XEUtils.searchTree(tableFullGroupData, () => true, {
800
+ original: true,
801
+ isEvery: true,
802
+ children: rowGroupOpts.mapChildrenField,
803
+ mapChildren: rowGroupOpts.childrenField
804
+ });
805
+ tableData = tableTree;
806
+ }
807
+ else if (treeConfig && transform) {
808
+ // 还原虚拟树
809
+ tableTree = XEUtils.searchTree(tableFullTreeData, () => true, {
810
+ original: true,
811
+ isEvery,
812
+ children: mapChildrenField,
813
+ mapChildren: childrenField
814
+ });
815
+ tableData = tableTree;
816
+ }
817
+ else {
818
+ tableData = treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0);
819
+ tableTree = tableData;
820
+ }
821
+ }
822
+ internalData.afterFullData = tableData;
823
+ internalData.afterTreeFullData = tableTree;
824
+ internalData.afterGroupFullData = tableTree;
825
+ updateAfterDataIndex($xeTable);
826
+ }
496
827
  function updateStyle($xeTable) {
497
828
  const props = $xeTable;
498
829
  const reactData = $xeTable;
@@ -903,7 +1234,7 @@ function handleCheckedRadioRow($xeTable, row, isForce) {
903
1234
  const reactData = $xeTable;
904
1235
  const radioOpts = $xeTable.computeRadioOpts;
905
1236
  const { checkMethod } = radioOpts;
906
- if (row && (isForce || (!checkMethod || checkMethod({ row })))) {
1237
+ if (row && (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row })))) {
907
1238
  reactData.selectRadioRow = row;
908
1239
  handleRadioReserveRow($xeTable, row);
909
1240
  }
@@ -922,8 +1253,10 @@ function handleCheckedAllCheckboxRow($xeTable, checked, isForce) {
922
1253
  const reactData = $xeTable;
923
1254
  const internalData = $xeTable;
924
1255
  const { treeConfig } = props;
925
- const { afterFullData, checkboxReserveRowMap, selectCheckboxMaps } = internalData;
1256
+ const { isRowGroupStatus } = reactData;
1257
+ const { afterFullData, afterTreeFullData, afterGroupFullData, checkboxReserveRowMap, selectCheckboxMaps } = internalData;
926
1258
  const treeOpts = $xeTable.computeTreeOpts;
1259
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
927
1260
  const childrenField = treeOpts.children || treeOpts.childrenField;
928
1261
  const checkboxOpts = $xeTable.computeCheckboxOpts;
929
1262
  const { checkField, reserve, checkMethod } = checkboxOpts;
@@ -932,24 +1265,24 @@ function handleCheckedAllCheckboxRow($xeTable, checked, isForce) {
932
1265
  const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
933
1266
  const selectRowMaps = {};
934
1267
  /**
935
- * 绑定属性方式(高性能,有污染)
1268
+ * 绑定属性方式(有污染)
936
1269
  * 必须在行数据存在对应的属性,否则将不响应
937
1270
  */
938
1271
  if (checkField) {
939
1272
  const checkValFn = (row) => {
940
- if (isForce || (!checkMethod || checkMethod({ row }))) {
1273
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
941
1274
  if (checked) {
942
1275
  selectRowMaps[handleGetRowId(row)] = row;
943
1276
  }
944
1277
  XEUtils.set(row, checkField, checked);
945
1278
  }
946
- if (treeConfig && indeterminateField) {
1279
+ if ((treeConfig || isRowGroupStatus) && indeterminateField) {
947
1280
  XEUtils.set(row, indeterminateField, false);
948
1281
  }
949
1282
  };
950
1283
  // 如果存在选中方法
951
1284
  // 如果方法成立,则更新值,否则忽略该数据
952
- if (treeConfig) {
1285
+ if ((treeConfig || isRowGroupStatus)) {
953
1286
  XEUtils.eachTree(afterFullData, checkValFn, { children: childrenField });
954
1287
  }
955
1288
  else {
@@ -958,17 +1291,45 @@ function handleCheckedAllCheckboxRow($xeTable, checked, isForce) {
958
1291
  }
959
1292
  else {
960
1293
  /**
961
- * 默认方式(低性能,无污染)
962
- * 无需任何属性,直接绑定
963
- */
964
- if (treeConfig) {
1294
+ * 默认方式(无污染)
1295
+ * 无需任何属性,直接绑定
1296
+ */
1297
+ if (isRowGroupStatus) {
965
1298
  if (checked) {
966
1299
  /**
967
- * 如果是树勾选
968
- * 如果方法成立,则添加到临时集合中
969
- */
970
- XEUtils.eachTree(afterFullData, (row) => {
971
- if (isForce || (!checkMethod || checkMethod({ row }))) {
1300
+ * 如果是行分组勾选
1301
+ * 如果方法成立,则添加到临时集合中
1302
+ */
1303
+ XEUtils.eachTree(afterGroupFullData, (row) => {
1304
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
1305
+ const rowid = handleGetRowId(row);
1306
+ selectRowMaps[rowid] = row;
1307
+ }
1308
+ }, { children: rowGroupOpts.mapChildrenField });
1309
+ }
1310
+ else {
1311
+ /**
1312
+ * 如果是树取消
1313
+ * 如果方法成立,则不添加到临时集合中
1314
+ */
1315
+ if (!isForce && checkMethod) {
1316
+ XEUtils.eachTree(afterGroupFullData, (row) => {
1317
+ const rowid = handleGetRowId(row);
1318
+ if (checkMethod({ $table: $xeTable, row }) ? false : selectCheckboxMaps[rowid]) {
1319
+ selectRowMaps[rowid] = row;
1320
+ }
1321
+ }, { children: rowGroupOpts.mapChildrenField });
1322
+ }
1323
+ }
1324
+ }
1325
+ else if (treeConfig) {
1326
+ if (checked) {
1327
+ /**
1328
+ * 如果是树勾选
1329
+ * 如果方法成立,则添加到临时集合中
1330
+ */
1331
+ XEUtils.eachTree(afterTreeFullData, (row) => {
1332
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
972
1333
  const rowid = handleGetRowId(row);
973
1334
  selectRowMaps[rowid] = row;
974
1335
  }
@@ -976,13 +1337,13 @@ function handleCheckedAllCheckboxRow($xeTable, checked, isForce) {
976
1337
  }
977
1338
  else {
978
1339
  /**
979
- * 如果是树取消
980
- * 如果方法成立,则不添加到临时集合中
981
- */
1340
+ * 如果是树取消
1341
+ * 如果方法成立,则不添加到临时集合中
1342
+ */
982
1343
  if (!isForce && checkMethod) {
983
- XEUtils.eachTree(afterFullData, (row) => {
1344
+ XEUtils.eachTree(afterTreeFullData, (row) => {
984
1345
  const rowid = handleGetRowId(row);
985
- if (checkMethod({ row }) ? 0 : selectCheckboxMaps[rowid]) {
1346
+ if (checkMethod({ $table: $xeTable, row }) ? false : selectCheckboxMaps[rowid]) {
986
1347
  selectRowMaps[rowid] = row;
987
1348
  }
988
1349
  }, { children: childrenField });
@@ -992,14 +1353,14 @@ function handleCheckedAllCheckboxRow($xeTable, checked, isForce) {
992
1353
  else {
993
1354
  if (checked) {
994
1355
  /**
995
- * 如果是行勾选
996
- * 如果存在选中方法且成立或者本身已勾选,则添加到临时集合中
997
- * 如果不存在选中方法,则添加所有数据到临时集合中
998
- */
1356
+ * 如果是行勾选
1357
+ * 如果存在选中方法且成立或者本身已勾选,则添加到临时集合中
1358
+ * 如果不存在选中方法,则添加所有数据到临时集合中
1359
+ */
999
1360
  if (!isForce && checkMethod) {
1000
1361
  afterFullData.forEach((row) => {
1001
1362
  const rowid = handleGetRowId(row);
1002
- if (selectCheckboxMaps[rowid] || checkMethod({ row })) {
1363
+ if (selectCheckboxMaps[rowid] || checkMethod({ $table: $xeTable, row })) {
1003
1364
  selectRowMaps[rowid] = row;
1004
1365
  }
1005
1366
  });
@@ -1013,14 +1374,14 @@ function handleCheckedAllCheckboxRow($xeTable, checked, isForce) {
1013
1374
  }
1014
1375
  else {
1015
1376
  /**
1016
- * 如果是行取消
1017
- * 如果方法成立,则不添加到临时集合中;如果方法不成立则判断当前是否已勾选,如果已被勾选则添加到新集合中
1018
- * 如果不存在选中方法,无需处理,临时集合默认为空
1019
- */
1377
+ * 如果是行取消
1378
+ * 如果方法成立,则不添加到临时集合中;如果方法不成立则判断当前是否已勾选,如果已被勾选则添加到新集合中
1379
+ * 如果不存在选中方法,无需处理,临时集合默认为空
1380
+ */
1020
1381
  if (!isForce && checkMethod) {
1021
1382
  afterFullData.forEach((row) => {
1022
1383
  const rowid = handleGetRowId(row);
1023
- if (checkMethod({ row }) ? 0 : selectCheckboxMaps[rowid]) {
1384
+ if (checkMethod({ $table: $xeTable, row }) ? false : selectCheckboxMaps[rowid]) {
1024
1385
  selectRowMaps[rowid] = row;
1025
1386
  }
1026
1387
  });
@@ -1764,9 +2125,11 @@ function updateRowDropTipContent($xeTable, tdEl) {
1764
2125
  const rTooltipMethod = tooltipMethod || (dragConfig ? dragConfig.rowTooltipMethod : null);
1765
2126
  let tipContent = '';
1766
2127
  if (rTooltipMethod) {
1767
- tipContent = `${rTooltipMethod({
2128
+ const rtParams = {
2129
+ $table: $xeTable,
1768
2130
  row: dragRow
1769
- }) || ''}`;
2131
+ };
2132
+ tipContent = `${rTooltipMethod(rtParams) || ''}`;
1770
2133
  }
1771
2134
  else {
1772
2135
  tipContent = getI18n('vxe.table.dragTip', [tdEl.textContent || '']);
@@ -1803,9 +2166,11 @@ function updateColDropTipContent($xeTable, tdEl) {
1803
2166
  const { tooltipMethod } = columnDragOpts;
1804
2167
  let tipContent = '';
1805
2168
  if (tooltipMethod) {
1806
- tipContent = `${tooltipMethod({
2169
+ const dtParams = {
2170
+ $table: $xeTable,
1807
2171
  column: dragCol
1808
- }) || ''}`;
2172
+ };
2173
+ tipContent = `${tooltipMethod(dtParams) || ''}`;
1809
2174
  }
1810
2175
  else {
1811
2176
  tipContent = getI18n('vxe.table.dragTip', [tdEl.textContent || '']);
@@ -2105,6 +2470,265 @@ function handleRecalculateLayout($xeTable, reFull) {
2105
2470
  }
2106
2471
  });
2107
2472
  }
2473
+ const handleUpdateRowGroup = ($xeTable, groupFields) => {
2474
+ const reactData = $xeTable;
2475
+ reactData.rowGroupList = groupFields
2476
+ ? (XEUtils.isArray(groupFields) ? groupFields : [groupFields]).map(field => {
2477
+ return {
2478
+ field
2479
+ };
2480
+ })
2481
+ : [];
2482
+ };
2483
+ function handleGroupData($xeTable, list, rowGroups) {
2484
+ let fullData = list;
2485
+ let treeData = list;
2486
+ if (rowGroups) {
2487
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
2488
+ const { rowField, parentField, childrenField, mapChildrenField } = rowGroupOpts;
2489
+ const checkboxOpts = $xeTable.computeCheckboxOpts;
2490
+ const { checkField } = checkboxOpts;
2491
+ const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
2492
+ const rgItem = rowGroups[0];
2493
+ if (rgItem && rowField && parentField && childrenField && mapChildrenField) {
2494
+ fullData = [];
2495
+ treeData = [];
2496
+ const groupField = rgItem.field;
2497
+ const groupColumn = $xeTable.getColumnByField(groupField);
2498
+ const groupMaps = {};
2499
+ const rowkey = getRowkey($xeTable);
2500
+ list.forEach((row) => {
2501
+ const cellValue = groupColumn ? $xeTable.getCellLabel(row, groupColumn) : XEUtils.get(row, groupField);
2502
+ const groupValue = XEUtils.eqNull(cellValue) ? '' : cellValue;
2503
+ let childList = groupMaps[groupValue];
2504
+ if (!childList) {
2505
+ childList = [];
2506
+ groupMaps[groupValue] = childList;
2507
+ }
2508
+ if (row.isAggregate) {
2509
+ row.isAggregate = undefined;
2510
+ }
2511
+ childList.push(row);
2512
+ });
2513
+ XEUtils.objectEach(groupMaps, (childList, groupValue) => {
2514
+ const { fullData: childFullData, treeData: childTreeData } = handleGroupData($xeTable, childList, rowGroups.slice(1));
2515
+ const groupRow = {
2516
+ isAggregate: true,
2517
+ groupContent: groupValue,
2518
+ groupField,
2519
+ [rowField]: getRowUniqueId(),
2520
+ [parentField]: null,
2521
+ [rowkey]: getRowUniqueId(),
2522
+ [childrenField]: childTreeData,
2523
+ [mapChildrenField]: childTreeData
2524
+ };
2525
+ if (checkField) {
2526
+ groupRow[checkField] = false;
2527
+ }
2528
+ if (indeterminateField) {
2529
+ groupRow[indeterminateField] = false;
2530
+ }
2531
+ treeData.push(groupRow);
2532
+ fullData.push(groupRow);
2533
+ if (childFullData.length) {
2534
+ fullData.push(...childFullData);
2535
+ }
2536
+ });
2537
+ }
2538
+ }
2539
+ return {
2540
+ treeData,
2541
+ fullData
2542
+ };
2543
+ }
2544
+ /**
2545
+ * 加载表格数据
2546
+ * @param {Array} datas 数据
2547
+ */
2548
+ function loadTableData($xeTable, datas, isReset) {
2549
+ const props = $xeTable;
2550
+ const reactData = $xeTable;
2551
+ const internalData = $xeTable;
2552
+ const { keepSource, treeConfig, rowGroupConfig } = props;
2553
+ const { rowGroupList, scrollYLoad: oldScrollYLoad } = reactData;
2554
+ const { scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop } = internalData;
2555
+ const rowOpts = $xeTable.computeRowOpts;
2556
+ const treeOpts = $xeTable.computeTreeOpts;
2557
+ const expandOpts = $xeTable.computeExpandOpts;
2558
+ const { transform } = treeOpts;
2559
+ const childrenField = treeOpts.children || treeOpts.childrenField;
2560
+ let treeData = [];
2561
+ let fullData = datas ? datas.slice(0) : []; // 转为响应式数据
2562
+ if (fullData.length > supportMaxRow) {
2563
+ errLog('vxe.error.errMaxRow', [supportMaxRow]);
2564
+ }
2565
+ if (treeConfig && rowGroupList.length) {
2566
+ errLog('vxe.error.noTree', ['row-group-config']);
2567
+ return $xeTable.$nextTick();
2568
+ }
2569
+ if (rowOpts.drag && rowGroupList.length) {
2570
+ errLog('vxe.error.errConflicts', ['row-config.drag', 'row-group-config']);
2571
+ return $xeTable.$nextTick();
2572
+ }
2573
+ let isRGroup = false;
2574
+ if (treeConfig) {
2575
+ if (transform) {
2576
+ // 树结构自动转换
2577
+ if (!treeOpts.rowField) {
2578
+ errLog('vxe.error.reqProp', ['tree-config.rowField']);
2579
+ }
2580
+ if (!treeOpts.parentField) {
2581
+ errLog('vxe.error.reqProp', ['tree-config.parentField']);
2582
+ }
2583
+ if (!childrenField) {
2584
+ errLog('vxe.error.reqProp', ['tree-config.childrenField']);
2585
+ }
2586
+ if (!treeOpts.mapChildrenField) {
2587
+ errLog('vxe.error.reqProp', ['tree-config.mapChildrenField']);
2588
+ }
2589
+ if (childrenField === treeOpts.mapChildrenField) {
2590
+ errLog('vxe.error.errConflicts', ['tree-config.childrenField', 'tree-config.mapChildrenField']);
2591
+ }
2592
+ // fullData.forEach(row => {
2593
+ // if (row[treeOpts.children] && row[treeOpts.children].length) {
2594
+ // warnLog('vxe.error.errConflicts', ['tree-config.transform', `row.${treeOpts.children}`])
2595
+ // }
2596
+ // })
2597
+ treeData = XEUtils.toArrayTree(fullData, {
2598
+ key: treeOpts.rowField,
2599
+ parentKey: treeOpts.parentField,
2600
+ children: childrenField,
2601
+ mapChildren: treeOpts.mapChildrenField
2602
+ });
2603
+ fullData = treeData.slice(0);
2604
+ }
2605
+ else {
2606
+ treeData = fullData.slice(0);
2607
+ }
2608
+ }
2609
+ else if (rowGroupConfig && rowGroupList.length) {
2610
+ const groupRest = handleGroupData($xeTable, fullData, rowGroupList);
2611
+ treeData = groupRest.treeData;
2612
+ fullData = groupRest.fullData;
2613
+ isRGroup = true;
2614
+ }
2615
+ reactData.isRowGroupStatus = isRGroup;
2616
+ scrollYStore.startIndex = 0;
2617
+ scrollYStore.endIndex = 1;
2618
+ scrollXStore.startIndex = 0;
2619
+ scrollXStore.endIndex = 1;
2620
+ reactData.isRowLoading = true;
2621
+ reactData.scrollVMLoading = false;
2622
+ internalData.treeExpandedMaps = {};
2623
+ reactData.treeExpandedFlag++;
2624
+ internalData.rowExpandedMaps = {};
2625
+ reactData.rowExpandedFlag++;
2626
+ internalData.insertRowMaps = {};
2627
+ reactData.insertRowFlag++;
2628
+ internalData.removeRowMaps = {};
2629
+ reactData.removeRowFlag++;
2630
+ const sYLoad = updateScrollYStatus($xeTable, fullData);
2631
+ reactData.isDragColMove = false;
2632
+ reactData.isDragRowMove = false;
2633
+ // 全量数据
2634
+ internalData.tableFullData = fullData;
2635
+ internalData.tableFullTreeData = isRGroup ? [] : treeData;
2636
+ internalData.tableFullGroupData = isRGroup ? treeData : [];
2637
+ // 缓存数据
2638
+ $xeTable.cacheRowMap(isReset);
2639
+ // 原始数据
2640
+ internalData.tableSynchData = datas;
2641
+ if (isReset) {
2642
+ internalData.isResizeCellHeight = false;
2643
+ }
2644
+ // 克隆原数据,用于显示编辑状态,与编辑值做对比
2645
+ if (keepSource) {
2646
+ $xeTable.cacheSourceMap(fullData);
2647
+ }
2648
+ if ($xeTable.clearCellAreas && props.mouseConfig) {
2649
+ $xeTable.clearCellAreas();
2650
+ $xeTable.clearCopyCellArea();
2651
+ }
2652
+ $xeTable.clearMergeCells();
2653
+ $xeTable.clearMergeFooterItems();
2654
+ $xeTable.handleTableData(true);
2655
+ $xeTable.updateFooter();
2656
+ $xeTable.handleUpdateBodyMerge();
2657
+ return $xeTable.$nextTick().then(() => {
2658
+ updateHeight($xeTable);
2659
+ updateStyle($xeTable);
2660
+ }).then(() => {
2661
+ computeScrollLoad($xeTable);
2662
+ }).then(() => {
2663
+ // 是否启用了虚拟滚动
2664
+ if (sYLoad) {
2665
+ scrollYStore.endIndex = scrollYStore.visibleSize;
2666
+ }
2667
+ if (sYLoad) {
2668
+ if (reactData.expandColumn && expandOpts.mode !== 'fixed') {
2669
+ errLog('vxe.error.notConflictProp', ['column.type="expand', 'expand-config.mode="fixed"']);
2670
+ }
2671
+ // if (showOverflow) {
2672
+ // if (!rowOpts.height) {
2673
+ // const errColumn = internalData.tableFullColumn.find(column => column.showOverflow === false)
2674
+ // if (errColumn) {
2675
+ // errLog('vxe.error.errProp', [`column[field="${errColumn.field}"].show-overflow=false`, 'show-overflow=true'])
2676
+ // }
2677
+ // }
2678
+ // }
2679
+ if (!(props.height || props.maxHeight)) {
2680
+ errLog('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}']);
2681
+ }
2682
+ // if (!props.showOverflow) {
2683
+ // warnLog('vxe.error.reqProp', ['table.show-overflow'])
2684
+ // }
2685
+ if (props.spanMethod) {
2686
+ errLog('vxe.error.scrollErrProp', ['table.span-method']);
2687
+ }
2688
+ }
2689
+ handleReserveStatus($xeTable);
2690
+ $xeTable.checkSelectionStatus();
2691
+ return new Promise(resolve => {
2692
+ $xeTable.$nextTick()
2693
+ .then(() => handleRecalculateLayout($xeTable, false))
2694
+ .then(() => {
2695
+ calcCellHeight($xeTable);
2696
+ updateRowOffsetTop($xeTable);
2697
+ return handleRecalculateLayout($xeTable, false);
2698
+ })
2699
+ .then(() => {
2700
+ let targetScrollLeft = lastScrollLeft;
2701
+ let targetScrollTop = lastScrollTop;
2702
+ const virtualXOpts = $xeTable.computeVirtualXOpts;
2703
+ const virtualYOpts = $xeTable.computeVirtualYOpts;
2704
+ // 是否在更新数据之后自动滚动重置滚动条
2705
+ if (virtualXOpts.scrollToLeftOnChange) {
2706
+ targetScrollLeft = 0;
2707
+ }
2708
+ if (virtualYOpts.scrollToTopOnChange) {
2709
+ targetScrollTop = 0;
2710
+ }
2711
+ reactData.isRowLoading = false;
2712
+ handleRecalculateLayout($xeTable, false);
2713
+ // 是否变更虚拟滚动
2714
+ if (oldScrollYLoad === sYLoad) {
2715
+ restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
2716
+ .then(() => {
2717
+ resolve();
2718
+ });
2719
+ }
2720
+ else {
2721
+ setTimeout(() => {
2722
+ restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
2723
+ .then(() => {
2724
+ resolve();
2725
+ });
2726
+ });
2727
+ }
2728
+ });
2729
+ });
2730
+ });
2731
+ }
2108
2732
  /**
2109
2733
  * 处理数据加载默认行为
2110
2734
  * 默认执行一次,除非被重置
@@ -2768,16 +3392,23 @@ const Methods = {
2768
3392
  clearAll() {
2769
3393
  return clearTableAllStatus(this);
2770
3394
  },
3395
+ handleUpdateRowGroup(groupFields) {
3396
+ const $xeTable = this;
3397
+ handleUpdateRowGroup($xeTable, groupFields);
3398
+ },
2771
3399
  /**
2772
3400
  * 同步 data 数据(即将废弃)
2773
3401
  * 如果用了该方法,那么组件将不再记录增删改的状态,只能自行实现对应逻辑
2774
3402
  * 对于某些特殊的场景,比如深层树节点元素发生变动时可能会用到
2775
3403
  */
2776
3404
  syncData() {
3405
+ const $xeTable = this;
3406
+ const reactData = $xeTable;
3407
+ const internalData = $xeTable;
2777
3408
  errLog('vxe.error.delFunc', ['syncData', 'getData']);
2778
- return this.$nextTick().then(() => {
2779
- this.tableData = [];
2780
- return this.$nextTick().then(() => this.loadTableData(this.tableFullData, true));
3409
+ return $xeTable.$nextTick().then(() => {
3410
+ reactData.tableData = [];
3411
+ return $xeTable.$nextTick().then(() => loadTableData($xeTable, internalData.tableFullData, true));
2781
3412
  });
2782
3413
  },
2783
3414
  /**
@@ -2800,205 +3431,48 @@ const Methods = {
2800
3431
  return $xeTable.refreshScroll();
2801
3432
  }
2802
3433
  }).then(() => {
2803
- $xeTable.updateCellAreas();
2804
- return $xeTable.recalculate(true);
2805
- }).then(() => {
2806
- // 存在滚动行为未结束情况
2807
- setTimeout(() => $xeTable.recalculate(), 50);
2808
- });
2809
- },
2810
- handleTableData(force) {
2811
- const $xeTable = this;
2812
- const reactData = $xeTable;
2813
- const internalData = $xeTable;
2814
- const { scrollYLoad } = reactData;
2815
- const { scrollYStore, fullDataRowIdData } = internalData;
2816
- let fullList = internalData.afterFullData;
2817
- // 是否进行数据处理
2818
- if (force) {
2819
- // 更新数据,处理筛选和排序
2820
- this.updateAfterFullData();
2821
- // 如果为虚拟树,将树结构拍平
2822
- fullList = handleVirtualTreeToList($xeTable);
2823
- }
2824
- const tableData = scrollYLoad ? fullList.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullList.slice(0);
2825
- const visibleDataRowIdMaps = {};
2826
- tableData.forEach((row, $index) => {
2827
- const rowid = getRowid(this, row);
2828
- const rest = fullDataRowIdData[rowid];
2829
- if (rest) {
2830
- rest.$index = $index;
2831
- }
2832
- visibleDataRowIdMaps[rowid] = row;
2833
- });
2834
- this.tableData = tableData;
2835
- internalData.visibleDataRowIdData = visibleDataRowIdMaps;
2836
- return this.$nextTick();
2837
- },
2838
- /**
2839
- * 加载表格数据
2840
- * @param {Array} datas 数据
2841
- */
2842
- loadTableData(datas, isReset) {
2843
- const $xeTable = this;
2844
- const props = $xeTable;
2845
- const reactData = $xeTable;
2846
- const internalData = $xeTable;
2847
- const { keepSource, treeConfig } = props;
2848
- const { scrollYLoad: oldScrollYLoad } = reactData;
2849
- const { scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop } = internalData;
2850
- const treeOpts = $xeTable.computeTreeOpts;
2851
- const expandOpts = $xeTable.computeExpandOpts;
2852
- const { transform } = treeOpts;
2853
- const childrenField = treeOpts.children || treeOpts.childrenField;
2854
- let treeData = [];
2855
- let fullData = datas ? datas.slice(0) : [];
2856
- if (fullData.length > supportMaxRow) {
2857
- errLog('vxe.error.errMaxRow', [supportMaxRow]);
2858
- }
2859
- if (treeConfig) {
2860
- // 树结构自动转换
2861
- if (transform) {
2862
- if (!treeOpts.rowField) {
2863
- errLog('vxe.error.reqProp', ['table.tree-config.rowField']);
2864
- }
2865
- if (!treeOpts.parentField) {
2866
- errLog('vxe.error.reqProp', ['table.tree-config.parentField']);
2867
- }
2868
- if (!childrenField) {
2869
- errLog('vxe.error.reqProp', ['tree-config.childrenField']);
2870
- }
2871
- if (!treeOpts.mapChildrenField) {
2872
- errLog('vxe.error.reqProp', ['tree-config.mapChildrenField']);
2873
- }
2874
- if (childrenField === treeOpts.mapChildrenField) {
2875
- errLog('vxe.error.errConflicts', ['tree-config.childrenField', 'tree-config.mapChildrenField']);
2876
- }
2877
- // fullData.forEach(row => {
2878
- // if (row[childrenField] && row[childrenField].length) {
2879
- // warnLog('vxe.error.errConflicts', ['tree-config.transform', `row.${childrenField}`])
2880
- // }
2881
- // })
2882
- treeData = XEUtils.toArrayTree(fullData, {
2883
- key: treeOpts.rowField,
2884
- parentKey: treeOpts.parentField,
2885
- children: childrenField,
2886
- mapChildren: treeOpts.mapChildrenField
2887
- });
2888
- fullData = treeData.slice(0);
2889
- }
2890
- else {
2891
- treeData = fullData.slice(0);
2892
- }
2893
- }
2894
- scrollYStore.startIndex = 0;
2895
- scrollYStore.endIndex = 1;
2896
- scrollXStore.startIndex = 0;
2897
- scrollXStore.endIndex = 1;
2898
- reactData.isRowLoading = true;
2899
- reactData.scrollVMLoading = false;
2900
- internalData.insertRowMaps = {};
2901
- internalData.removeRowMaps = {};
2902
- const sYLoad = updateScrollYStatus($xeTable, fullData);
2903
- reactData.isDragColMove = false;
2904
- reactData.isDragRowMove = false;
2905
- // 全量数据
2906
- internalData.tableFullData = fullData;
2907
- internalData.tableFullTreeData = treeData;
2908
- // 缓存数据
2909
- $xeTable.cacheRowMap(isReset);
2910
- // 原始数据
2911
- internalData.tableSynchData = datas;
2912
- if (isReset) {
2913
- internalData.isResizeCellHeight = false;
2914
- }
2915
- // 克隆原数据,用于显示编辑状态,与编辑值做对比
2916
- if (keepSource) {
2917
- $xeTable.cacheSourceMap(fullData);
2918
- }
2919
- if ($xeTable.clearCellAreas && props.mouseConfig) {
2920
- $xeTable.clearCellAreas();
2921
- $xeTable.clearCopyCellArea();
2922
- }
2923
- $xeTable.clearMergeCells();
2924
- $xeTable.clearMergeFooterItems();
2925
- $xeTable.handleTableData(true);
2926
- $xeTable.updateFooter();
2927
- $xeTable.handleUpdateBodyMerge();
2928
- return $xeTable.$nextTick().then(() => {
2929
- updateHeight($xeTable);
2930
- updateStyle($xeTable);
2931
- }).then(() => {
2932
- computeScrollLoad($xeTable);
3434
+ $xeTable.updateCellAreas();
3435
+ return $xeTable.recalculate(true);
2933
3436
  }).then(() => {
2934
- // 是否启用了虚拟滚动
2935
- if (sYLoad) {
2936
- scrollYStore.endIndex = scrollYStore.visibleSize;
2937
- }
2938
- if (sYLoad) {
2939
- if (reactData.expandColumn && expandOpts.mode !== 'fixed') {
2940
- errLog('vxe.error.notConflictProp', ['column.type="expand', 'expand-config.mode="fixed"']);
2941
- }
2942
- // if (showOverflow) {
2943
- // if (!rowOpts.height) {
2944
- // const errColumn = internalData.tableFullColumn.find((column: any) => column.showOverflow === false)
2945
- // if (errColumn) {
2946
- // errLog('vxe.error.errProp', [`column[field="${errColumn.field}"].show-overflow=false`, 'show-overflow=true'])
2947
- // }
2948
- // }
2949
- // }
2950
- if (!(props.height || props.maxHeight)) {
2951
- errLog('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}']);
2952
- }
2953
- // if (!props.showOverflow) {
2954
- // warnLog('vxe.error.reqProp', ['table.show-overflow'])
2955
- // }
2956
- if (props.spanMethod) {
2957
- errLog('vxe.error.scrollErrProp', ['table.span-method']);
2958
- }
2959
- }
2960
- handleReserveStatus($xeTable);
2961
- $xeTable.checkSelectionStatus();
2962
- return new Promise(resolve => {
2963
- this.$nextTick()
2964
- .then(() => handleRecalculateLayout($xeTable, false))
2965
- .then(() => {
2966
- calcCellHeight($xeTable);
2967
- updateRowOffsetTop($xeTable);
2968
- return handleRecalculateLayout($xeTable, false);
2969
- })
2970
- .then(() => {
2971
- let targetScrollLeft = lastScrollLeft;
2972
- let targetScrollTop = lastScrollTop;
2973
- const virtualXOpts = $xeTable.computeVirtualXOpts;
2974
- const virtualYOpts = $xeTable.computeVirtualYOpts;
2975
- // 是否在更新数据之后自动滚动重置滚动条
2976
- if (virtualXOpts.scrollToLeftOnChange) {
2977
- targetScrollLeft = 0;
2978
- }
2979
- if (virtualYOpts.scrollToTopOnChange) {
2980
- targetScrollTop = 0;
2981
- }
2982
- reactData.isRowLoading = false;
2983
- handleRecalculateLayout($xeTable, false);
2984
- // 是否变更虚拟滚动
2985
- if (oldScrollYLoad === sYLoad) {
2986
- restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
2987
- .then(() => {
2988
- resolve();
2989
- });
2990
- }
2991
- else {
2992
- setTimeout(() => {
2993
- restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
2994
- .then(() => {
2995
- resolve();
2996
- });
2997
- });
2998
- }
2999
- });
3000
- });
3437
+ // 存在滚动行为未结束情况
3438
+ setTimeout(() => $xeTable.recalculate(), 50);
3439
+ });
3440
+ },
3441
+ handleTableData(force) {
3442
+ const $xeTable = this;
3443
+ const reactData = $xeTable;
3444
+ const internalData = $xeTable;
3445
+ const { scrollYLoad } = reactData;
3446
+ const { scrollYStore, fullDataRowIdData } = internalData;
3447
+ let fullList = internalData.afterFullData;
3448
+ // 是否进行数据处理
3449
+ if (force) {
3450
+ // 更新数据,处理筛选和排序
3451
+ updateAfterFullData($xeTable);
3452
+ // 如果为虚拟树,将树结构拍平
3453
+ fullList = handleVirtualTreeToList($xeTable);
3454
+ }
3455
+ const tableData = scrollYLoad ? fullList.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullList.slice(0);
3456
+ const visibleDataRowIdMaps = {};
3457
+ tableData.forEach((row, $index) => {
3458
+ const rowid = getRowid($xeTable, row);
3459
+ const rest = fullDataRowIdData[rowid];
3460
+ if (rest) {
3461
+ rest.$index = $index;
3462
+ }
3463
+ visibleDataRowIdMaps[rowid] = row;
3001
3464
  });
3465
+ reactData.tableData = tableData;
3466
+ internalData.visibleDataRowIdData = visibleDataRowIdMaps;
3467
+ return $xeTable.$nextTick();
3468
+ },
3469
+ /**
3470
+ * 加载表格数据
3471
+ * @param {Array} datas 数据
3472
+ */
3473
+ loadTableData(datas, isReset) {
3474
+ const $xeTable = this;
3475
+ return loadTableData($xeTable, datas, isReset);
3002
3476
  },
3003
3477
  /**
3004
3478
  * 重新加载数据,不会清空表格状态
@@ -3007,7 +3481,7 @@ const Methods = {
3007
3481
  loadData(datas) {
3008
3482
  const $xeTable = this;
3009
3483
  const { initStatus } = this;
3010
- return this.loadTableData(datas, false).then(() => {
3484
+ return loadTableData($xeTable, datas, false).then(() => {
3011
3485
  this.inited = true;
3012
3486
  this.initStatus = true;
3013
3487
  if (!initStatus) {
@@ -3026,7 +3500,7 @@ const Methods = {
3026
3500
  .then(() => {
3027
3501
  this.inited = true;
3028
3502
  this.initStatus = true;
3029
- return this.loadTableData(datas, true);
3503
+ return loadTableData($xeTable, datas, true);
3030
3504
  })
3031
3505
  .then(() => {
3032
3506
  handleLoadDefaults($xeTable);
@@ -3111,11 +3585,8 @@ const Methods = {
3111
3585
  const reactData = $xeTable;
3112
3586
  const internalData = $xeTable;
3113
3587
  const { treeConfig } = props;
3114
- const { fullAllDataRowIdData, tableFullData, tableFullTreeData, treeExpandedMaps } = internalData;
3115
- const treeOpts = $xeTable.computeTreeOpts;
3116
- const childrenField = treeOpts.children || treeOpts.childrenField;
3117
- const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
3118
- const { lazy } = treeOpts;
3588
+ const { isRowGroupStatus } = reactData;
3589
+ const { fullAllDataRowIdData, tableFullData, tableFullTreeData, tableFullGroupData, treeExpandedMaps } = internalData;
3119
3590
  const fullAllDataRowIdMaps = isReset ? {} : Object.assign({}, fullAllDataRowIdData); // 存在已删除数据
3120
3591
  const fullDataRowIdMaps = {};
3121
3592
  const { handleUpdateRowId } = createHandleUpdateRowId($xeTable);
@@ -3136,6 +3607,10 @@ const Methods = {
3136
3607
  fullAllDataRowIdMaps[rowid] = rowRest;
3137
3608
  };
3138
3609
  if (treeConfig) {
3610
+ const treeOpts = $xeTable.computeTreeOpts;
3611
+ const { lazy } = treeOpts;
3612
+ const childrenField = treeOpts.children || treeOpts.childrenField;
3613
+ const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
3139
3614
  XEUtils.eachTree(tableFullTreeData, (row, index, items, path, parentRow, nodes) => {
3140
3615
  const rowid = handleUpdateRowId(row);
3141
3616
  if (treeConfig && lazy) {
@@ -3151,6 +3626,14 @@ const Methods = {
3151
3626
  handleRowCache(row, index, items, parentRow ? -1 : index, parentRow, rowid, nodes.length - 1, toTreePathSeq(path));
3152
3627
  }, { children: childrenField });
3153
3628
  }
3629
+ else if (isRowGroupStatus) {
3630
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
3631
+ const { mapChildrenField } = rowGroupOpts;
3632
+ XEUtils.eachTree(tableFullGroupData, (row, index, items, path, parentRow, nodes) => {
3633
+ const rowid = handleUpdateRowId(row);
3634
+ handleRowCache(row, index, items, parentRow ? -1 : index, parentRow, rowid, nodes.length - 1, toTreePathSeq(path));
3635
+ }, { children: mapChildrenField });
3636
+ }
3154
3637
  else {
3155
3638
  tableFullData.forEach((row, index, items) => {
3156
3639
  handleRowCache(row, index, items, index, null, handleUpdateRowId(row), 0, index + 1);
@@ -3893,174 +4376,6 @@ const Methods = {
3893
4376
  }
3894
4377
  return rowList;
3895
4378
  },
3896
- /**
3897
- * 获取处理后全量的表格数据
3898
- * 如果存在筛选条件,继续处理
3899
- */
3900
- updateAfterFullData() {
3901
- const $xeTable = this;
3902
- const props = $xeTable;
3903
- const internalData = $xeTable;
3904
- const { treeConfig } = props;
3905
- const { tableFullColumn, tableFullData, tableFullTreeData } = internalData;
3906
- const filterOpts = $xeTable.computeFilterOpts;
3907
- const sortOpts = $xeTable.computeSortOpts;
3908
- const treeOpts = $xeTable.computeTreeOpts;
3909
- const childrenField = treeOpts.children || treeOpts.childrenField;
3910
- const { transform, rowField, parentField, mapChildrenField } = treeOpts;
3911
- const { isEvery, remote: allRemoteFilter, filterMethod: allFilterMethod } = filterOpts;
3912
- const { remote: allRemoteSort, sortMethod: allSortMethod, multiple: sortMultiple, chronological } = sortOpts;
3913
- let tableData = [];
3914
- let tableTree = [];
3915
- // 处理数据
3916
- if (!allRemoteFilter || !allRemoteSort) {
3917
- const filterColumns = [];
3918
- let orderColumns = [];
3919
- tableFullColumn.forEach((column) => {
3920
- const { field, sortable, order, filters } = column;
3921
- if (!allRemoteFilter && filters && filters.length) {
3922
- const valueList = [];
3923
- const itemList = [];
3924
- filters.forEach((item) => {
3925
- if (item.checked) {
3926
- itemList.push(item);
3927
- valueList.push(item.value);
3928
- }
3929
- });
3930
- if (itemList.length) {
3931
- filterColumns.push({ column, valueList, itemList });
3932
- }
3933
- }
3934
- if (!allRemoteSort && sortable && order) {
3935
- orderColumns.push({ column, field, property: field, order: order, sortTime: column.sortTime });
3936
- }
3937
- });
3938
- if (sortMultiple && chronological && orderColumns.length > 1) {
3939
- orderColumns = XEUtils.orderBy(orderColumns, 'sortTime');
3940
- }
3941
- // 处理筛选
3942
- // 支持单列、多列、组合筛选
3943
- if (!allRemoteFilter && filterColumns.length) {
3944
- const handleFilter = (row) => {
3945
- return filterColumns.every(({ column, valueList, itemList }) => {
3946
- const { filterMethod, filterRender } = column;
3947
- const compConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null;
3948
- const compFilterMethod = compConf ? (compConf.tableFilterMethod || compConf.filterMethod) : null;
3949
- const tdFilterMethod = compConf ? (compConf.tableFilterDefaultMethod || compConf.defaultTableFilterMethod || compConf.defaultFilterMethod) : null;
3950
- const cellValue = getCellValue(row, column);
3951
- if (filterMethod) {
3952
- return itemList.some((item) => filterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
3953
- }
3954
- else if (compFilterMethod) {
3955
- return itemList.some((item) => compFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
3956
- }
3957
- else if (allFilterMethod) {
3958
- return allFilterMethod({ options: itemList, values: valueList, cellValue, row, column });
3959
- }
3960
- else if (tdFilterMethod) {
3961
- return itemList.some((item) => tdFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: $xeTable }));
3962
- }
3963
- return valueList.indexOf(XEUtils.get(row, column.field)) > -1;
3964
- });
3965
- };
3966
- if (treeConfig && transform) {
3967
- // 筛选虚拟树
3968
- tableTree = XEUtils.searchTree(tableFullTreeData, handleFilter, {
3969
- original: true,
3970
- isEvery,
3971
- children: mapChildrenField,
3972
- mapChildren: childrenField
3973
- });
3974
- tableData = tableTree;
3975
- }
3976
- else {
3977
- tableData = treeConfig ? tableFullTreeData.filter(handleFilter) : tableFullData.filter(handleFilter);
3978
- tableTree = tableData;
3979
- }
3980
- }
3981
- else {
3982
- if (treeConfig && transform) {
3983
- // 还原虚拟树
3984
- tableTree = XEUtils.searchTree(tableFullTreeData, () => true, {
3985
- original: true,
3986
- isEvery,
3987
- children: mapChildrenField,
3988
- mapChildren: childrenField
3989
- });
3990
- tableData = tableTree;
3991
- }
3992
- else {
3993
- tableData = treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0);
3994
- tableTree = tableData;
3995
- }
3996
- }
3997
- // 处理排序(不能用于树形结构)
3998
- // 支持单列、多列、组合排序
3999
- if (!allRemoteSort && orderColumns.length) {
4000
- if (treeConfig && transform) {
4001
- // 虚拟树和列表一样,只能排序根级节点
4002
- if (allSortMethod) {
4003
- const sortRests = allSortMethod({ data: tableTree, sortList: orderColumns, $table: $xeTable });
4004
- tableTree = XEUtils.isArray(sortRests) ? sortRests : tableTree;
4005
- }
4006
- else {
4007
- const treeList = XEUtils.toTreeArray(tableTree, {
4008
- children: mapChildrenField
4009
- });
4010
- tableTree = XEUtils.toArrayTree(XEUtils.orderBy(treeList, orderColumns.map(({ column, order }) => [getOrderField($xeTable, column), order])), {
4011
- key: rowField,
4012
- parentKey: parentField,
4013
- children: childrenField,
4014
- mapChildren: mapChildrenField
4015
- });
4016
- }
4017
- tableData = tableTree;
4018
- }
4019
- else {
4020
- if (allSortMethod) {
4021
- const sortRests = allSortMethod({ data: tableData, sortList: orderColumns, $table: $xeTable });
4022
- tableData = XEUtils.isArray(sortRests) ? sortRests : tableData;
4023
- }
4024
- else {
4025
- // 兼容 v4
4026
- if (sortMultiple) {
4027
- tableData = XEUtils.orderBy(tableData, orderColumns.map(({ column, order }) => [getOrderField(this, column), order]));
4028
- }
4029
- else {
4030
- const firstOrderColumn = orderColumns[0];
4031
- let sortByConfs;
4032
- // 已废弃,兼容 v2,在 v4 中废弃, sortBy 不能为数组
4033
- if (XEUtils.isArray(firstOrderColumn.sortBy)) {
4034
- sortByConfs = firstOrderColumn.sortBy.map((item) => [item, firstOrderColumn.order]);
4035
- }
4036
- tableData = XEUtils.orderBy(tableData, sortByConfs || [firstOrderColumn].map(({ column, order }) => [getOrderField(this, column), order]));
4037
- }
4038
- tableData = XEUtils.orderBy(tableData, orderColumns.map(({ column, order }) => [getOrderField($xeTable, column), order]));
4039
- }
4040
- tableTree = tableData;
4041
- }
4042
- }
4043
- }
4044
- else {
4045
- if (treeConfig && transform) {
4046
- // 还原虚拟树
4047
- tableTree = XEUtils.searchTree(tableFullTreeData, () => true, {
4048
- original: true,
4049
- isEvery,
4050
- children: treeOpts.mapChildrenField,
4051
- mapChildren: childrenField
4052
- });
4053
- tableData = tableTree;
4054
- }
4055
- else {
4056
- tableData = treeConfig ? tableFullTreeData.slice(0) : tableFullData.slice(0);
4057
- tableTree = tableData;
4058
- }
4059
- }
4060
- internalData.afterFullData = tableData;
4061
- internalData.afterTreeFullData = tableTree;
4062
- updateAfterDataIndex($xeTable);
4063
- },
4064
4379
  /**
4065
4380
  * 预编译
4066
4381
  * 对渲染中的数据提前解析序号及索引。牺牲提前编译耗时换取渲染中额外损耗,使运行时更加流畅
@@ -4401,7 +4716,7 @@ const Methods = {
4401
4716
  }
4402
4717
  const storeData = getCustomStorageMap(tableId);
4403
4718
  if (restoreStore) {
4404
- return Promise.resolve(restoreStore({ id: tableId, type: 'restore', storeData })).then(storeData => {
4719
+ return Promise.resolve(restoreStore({ $table: $xeTable, id: tableId, type: 'restore', storeData })).then(storeData => {
4405
4720
  if (!storeData) {
4406
4721
  return;
4407
4722
  }
@@ -4466,7 +4781,7 @@ const Methods = {
4466
4781
  hasResizable = 1;
4467
4782
  resizableData[colKey] = column.renderWidth;
4468
4783
  }
4469
- if (isCustomVisible && (!checkMethod || checkMethod({ column }))) {
4784
+ if (isCustomVisible && (!checkMethod || checkMethod({ $table: $xeTable, column }))) {
4470
4785
  if (!column.visible && column.defaultVisible) {
4471
4786
  hasVisible = 1;
4472
4787
  visibleData[colKey] = false;
@@ -4523,6 +4838,7 @@ const Methods = {
4523
4838
  : this.getCustomStoreData();
4524
4839
  if (updateStore) {
4525
4840
  return updateStore({
4841
+ $table: $xeTable,
4526
4842
  id: tableId,
4527
4843
  type,
4528
4844
  storeData
@@ -5400,8 +5716,7 @@ const Methods = {
5400
5716
  const hasDeleteKey = keyCode === 46;
5401
5717
  const isF2 = keyCode === 113;
5402
5718
  const isContextMenu = keyCode === 93;
5403
- const hasMetaKey = evnt.metaKey;
5404
- const hasCtrlKey = evnt.ctrlKey;
5719
+ const isControlKey = hasControlKey(evnt);
5405
5720
  const hasShiftKey = evnt.shiftKey;
5406
5721
  const hasAltKey = evnt.altKey;
5407
5722
  const operArrow = isLeftArrow || isUpArrow || isRightArrow || isDwArrow;
@@ -5471,7 +5786,7 @@ const Methods = {
5471
5786
  else if (isEnter && !hasAltKey && keyboardConfig && keyboardOpts.isEnter && (selected.row || actived.row || (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow))) {
5472
5787
  const { isLastEnterAppendRow, beforeEnterMethod, enterMethod } = keyboardOpts;
5473
5788
  // 退出选中
5474
- if (hasCtrlKey) {
5789
+ if (isControlKey) {
5475
5790
  // 如果是激活编辑状态,则取消编辑
5476
5791
  if (actived.row) {
5477
5792
  const params = actived.args;
@@ -5652,7 +5967,7 @@ const Methods = {
5652
5967
  .then(() => $xeTable.triggerCurrentRowEvent(evnt, params));
5653
5968
  }
5654
5969
  }
5655
- else if (keyboardConfig && keyboardOpts.isEdit && !hasCtrlKey && !hasMetaKey && (isSpacebar || (keyCode >= 48 && keyCode <= 57) || (keyCode >= 65 && keyCode <= 90) || (keyCode >= 96 && keyCode <= 111) || (keyCode >= 186 && keyCode <= 192) || (keyCode >= 219 && keyCode <= 222))) {
5970
+ else if (keyboardConfig && keyboardOpts.isEdit && !isControlKey && (isSpacebar || (keyCode >= 48 && keyCode <= 57) || (keyCode >= 65 && keyCode <= 90) || (keyCode >= 96 && keyCode <= 111) || (keyCode >= 186 && keyCode <= 192) || (keyCode >= 219 && keyCode <= 222))) {
5656
5971
  const { editMethod } = keyboardOpts;
5657
5972
  // 启用编辑后,空格键功能将失效
5658
5973
  // if (isSpacebar) {
@@ -6015,7 +6330,9 @@ const Methods = {
6015
6330
  const reactData = $xeTable;
6016
6331
  const internalData = $xeTable;
6017
6332
  const { treeConfig } = props;
6333
+ const { isRowGroupStatus } = reactData;
6018
6334
  const { selectCheckboxMaps } = internalData;
6335
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
6019
6336
  const treeOpts = $xeTable.computeTreeOpts;
6020
6337
  const { transform, mapChildrenField } = treeOpts;
6021
6338
  const childrenField = treeOpts.children || treeOpts.childrenField;
@@ -6026,10 +6343,10 @@ const Methods = {
6026
6343
  const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
6027
6344
  if (checkField) {
6028
6345
  // 树结构
6029
- if (treeConfig && !checkStrictly) {
6346
+ if ((treeConfig || isRowGroupStatus) && !checkStrictly) {
6030
6347
  // 更新子节点状态
6031
6348
  XEUtils.eachTree(rows, (row) => {
6032
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6349
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6033
6350
  XEUtils.set(row, checkField, checked);
6034
6351
  if (indeterminateField) {
6035
6352
  XEUtils.set(row, indeterminateField, false);
@@ -6042,7 +6359,7 @@ const Methods = {
6042
6359
  }
6043
6360
  // 列表
6044
6361
  rows.forEach(row => {
6045
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6362
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6046
6363
  XEUtils.set(row, checkField, checked);
6047
6364
  handleCheckboxReserveRow($xeTable, row, checked);
6048
6365
  }
@@ -6051,29 +6368,50 @@ const Methods = {
6051
6368
  return;
6052
6369
  }
6053
6370
  // 树结构
6054
- if (treeConfig && !checkStrictly) {
6055
- // 更新子节点状态
6056
- XEUtils.eachTree(rows, (row) => {
6057
- const rowid = handleGetRowId(row);
6058
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6059
- if (checked) {
6060
- selectCheckboxMaps[rowid] = row;
6371
+ if (!checkStrictly) {
6372
+ if (isRowGroupStatus) {
6373
+ // 更新行分组节点状态
6374
+ XEUtils.eachTree(rows, (row) => {
6375
+ const rowid = handleGetRowId(row);
6376
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6377
+ if (checked) {
6378
+ selectCheckboxMaps[rowid] = row;
6379
+ }
6380
+ else {
6381
+ if (selectCheckboxMaps[rowid]) {
6382
+ delete selectCheckboxMaps[rowid];
6383
+ }
6384
+ }
6385
+ handleCheckboxReserveRow($xeTable, row, checked);
6061
6386
  }
6062
- else {
6063
- if (selectCheckboxMaps[rowid]) {
6064
- delete selectCheckboxMaps[rowid];
6387
+ }, { children: rowGroupOpts.mapChildrenField });
6388
+ reactData.updateCheckboxFlag++;
6389
+ return;
6390
+ }
6391
+ else if (treeConfig) {
6392
+ // 更新子节点状态
6393
+ XEUtils.eachTree(rows, (row) => {
6394
+ const rowid = handleGetRowId(row);
6395
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6396
+ if (checked) {
6397
+ selectCheckboxMaps[rowid] = row;
6398
+ }
6399
+ else {
6400
+ if (selectCheckboxMaps[rowid]) {
6401
+ delete selectCheckboxMaps[rowid];
6402
+ }
6065
6403
  }
6404
+ handleCheckboxReserveRow($xeTable, row, checked);
6066
6405
  }
6067
- handleCheckboxReserveRow($xeTable, row, checked);
6068
- }
6069
- }, { children: transform ? mapChildrenField : childrenField });
6070
- reactData.updateCheckboxFlag++;
6071
- return;
6406
+ }, { children: transform ? mapChildrenField : childrenField });
6407
+ reactData.updateCheckboxFlag++;
6408
+ return;
6409
+ }
6072
6410
  }
6073
6411
  // 列表
6074
6412
  rows.forEach(row => {
6075
6413
  const rowid = handleGetRowId(row);
6076
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6414
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6077
6415
  if (checked) {
6078
6416
  if (!selectCheckboxMaps[rowid]) {
6079
6417
  selectCheckboxMaps[rowid] = row;
@@ -6125,8 +6463,11 @@ const Methods = {
6125
6463
  triggerCheckRowEvent(evnt, params, checked) {
6126
6464
  const $xeTable = this;
6127
6465
  const props = $xeTable;
6466
+ const reactData = $xeTable;
6128
6467
  const internalData = $xeTable;
6468
+ const { treeConfig } = props;
6129
6469
  const { row } = params;
6470
+ const { isRowGroupStatus } = reactData;
6130
6471
  const { afterFullData } = internalData;
6131
6472
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6132
6473
  const { checkMethod, trigger } = checkboxOpts;
@@ -6134,7 +6475,7 @@ const Methods = {
6134
6475
  return;
6135
6476
  }
6136
6477
  evnt.stopPropagation();
6137
- if (checkboxOpts.isShiftKey && evnt.shiftKey && !props.treeConfig) {
6478
+ if (checkboxOpts.isShiftKey && evnt.shiftKey && !(treeConfig || isRowGroupStatus)) {
6138
6479
  const checkboxRecords = $xeTable.getCheckboxRecords();
6139
6480
  if (checkboxRecords.length) {
6140
6481
  const firstRow = checkboxRecords[0];
@@ -6151,7 +6492,7 @@ const Methods = {
6151
6492
  }
6152
6493
  }
6153
6494
  }
6154
- if (!checkMethod || checkMethod({ row })) {
6495
+ if (!checkMethod || checkMethod({ $table: $xeTable, row })) {
6155
6496
  $xeTable.handleBatchSelectRows([row], checked);
6156
6497
  $xeTable.checkSelectionStatus();
6157
6498
  $xeTable.dispatchEvent('checkbox-change', Object.assign({
@@ -6190,29 +6531,46 @@ const Methods = {
6190
6531
  const reactData = $xeTable;
6191
6532
  const internalData = $xeTable;
6192
6533
  const { treeConfig } = props;
6193
- const { selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6534
+ const { isRowGroupStatus } = reactData;
6535
+ const { afterTreeFullData, afterGroupFullData, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6536
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
6194
6537
  const treeOpts = $xeTable.computeTreeOpts;
6195
- const { transform, mapChildrenField } = treeOpts;
6196
6538
  const childrenField = treeOpts.children || treeOpts.childrenField;
6197
6539
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6198
6540
  const { checkField, checkStrictly, checkMethod } = checkboxOpts;
6199
- const { afterTreeFullData } = internalData;
6200
6541
  if (checkStrictly) {
6201
6542
  return;
6202
6543
  }
6203
- // 树结构
6204
- if (treeConfig) {
6544
+ if (isRowGroupStatus || treeConfig) {
6205
6545
  const { handleGetRowId } = createHandleGetRowId($xeTable);
6206
6546
  const childRowMaps = {};
6207
6547
  const childRowList = [];
6208
- XEUtils.eachTree(afterTreeFullData, (row) => {
6209
- const rowid = handleGetRowId(row);
6210
- const childList = row[transform ? mapChildrenField : childrenField];
6211
- if (childList && childList.length && !childRowMaps[rowid]) {
6212
- childRowMaps[rowid] = 1;
6213
- childRowList.unshift([row, rowid, childList]);
6548
+ if (isRowGroupStatus) {
6549
+ // 行分组
6550
+ const mapChildrenField = rowGroupOpts.mapChildrenField;
6551
+ if (mapChildrenField) {
6552
+ XEUtils.eachTree(afterGroupFullData, (row) => {
6553
+ const rowid = handleGetRowId(row);
6554
+ const childList = row[mapChildrenField];
6555
+ if (childList && childList.length && !childRowMaps[rowid]) {
6556
+ childRowMaps[rowid] = 1;
6557
+ childRowList.unshift([row, rowid, childList]);
6558
+ }
6559
+ }, { children: mapChildrenField });
6214
6560
  }
6215
- }, { children: transform ? mapChildrenField : childrenField });
6561
+ }
6562
+ else if (treeConfig) {
6563
+ // 树结构
6564
+ const { transform, mapChildrenField } = treeOpts;
6565
+ XEUtils.eachTree(afterTreeFullData, (row) => {
6566
+ const rowid = handleGetRowId(row);
6567
+ const childList = row[transform ? mapChildrenField : childrenField];
6568
+ if (childList && childList.length && !childRowMaps[rowid]) {
6569
+ childRowMaps[rowid] = 1;
6570
+ childRowList.unshift([row, rowid, childList]);
6571
+ }
6572
+ }, { children: transform ? mapChildrenField : childrenField });
6573
+ }
6216
6574
  childRowList.forEach(vals => {
6217
6575
  const row = vals[0];
6218
6576
  const rowid = vals[1];
@@ -6224,7 +6582,7 @@ const Methods = {
6224
6582
  ? (item) => {
6225
6583
  const childRowid = handleGetRowId(item);
6226
6584
  const isSelect = checkField ? XEUtils.get(item, checkField) : selectCheckboxMaps[childRowid];
6227
- if (checkMethod({ row: item })) {
6585
+ if (checkMethod({ $table: $xeTable, row: item })) {
6228
6586
  if (isSelect) {
6229
6587
  sLen++;
6230
6588
  }
@@ -6291,19 +6649,20 @@ const Methods = {
6291
6649
  const reactData = $xeTable;
6292
6650
  const internalData = $xeTable;
6293
6651
  const { treeConfig } = props;
6294
- const { afterFullData, afterTreeFullData, checkboxReserveRowMap, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6652
+ const { isRowGroupStatus } = reactData;
6653
+ const { afterFullData, afterTreeFullData, afterGroupFullData, checkboxReserveRowMap, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6295
6654
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6296
6655
  const { checkField, checkMethod, showReserveStatus } = checkboxOpts;
6297
6656
  const { handleGetRowId } = createHandleGetRowId($xeTable);
6298
6657
  let sLen = 0; // 已选
6299
6658
  let hLen = 0; // 半选
6300
6659
  let vLen = 0; // 有效行
6301
- const rootList = (treeConfig ? afterTreeFullData : afterFullData);
6660
+ const rootList = (treeConfig ? afterTreeFullData : (isRowGroupStatus ? afterGroupFullData : afterFullData));
6302
6661
  rootList.forEach(checkMethod
6303
6662
  ? row => {
6304
6663
  const childRowid = handleGetRowId(row);
6305
6664
  const selected = checkField ? XEUtils.get(row, checkField) : selectCheckboxMaps[childRowid];
6306
- if (checkMethod({ row })) {
6665
+ if (checkMethod({ $table: $xeTable, row })) {
6307
6666
  if (selected) {
6308
6667
  sLen++;
6309
6668
  }
@@ -6793,20 +7152,22 @@ const Methods = {
6793
7152
  const radioOpts = $xeTable.computeRadioOpts;
6794
7153
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6795
7154
  const keyboardOpts = $xeTable.computeKeyboardOpts;
7155
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
6796
7156
  const rowOpts = $xeTable.computeRowOpts;
6797
7157
  const columnOpts = $xeTable.computeColumnOpts;
6798
7158
  const currentColumnOpts = $xeTable.computeCurrentColumnOpts;
6799
7159
  const { actived, focused } = editStore;
6800
7160
  const { row, column } = params;
6801
- const { type, treeNode } = column;
7161
+ const { type, treeNode, rowGroupNode } = column;
6802
7162
  const isRadioType = type === 'radio';
6803
7163
  const isCheckboxType = type === 'checkbox';
6804
7164
  const isExpandType = type === 'expand';
6805
7165
  const cell = evnt.currentTarget;
6806
7166
  const triggerRadio = isRadioType && getEventTargetNode(evnt, cell, 'vxe-cell--radio').flag;
6807
7167
  const triggerCheckbox = isCheckboxType && getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
6808
- const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-tree--btn-wrapper').flag;
7168
+ const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-cell--tree-btn').flag;
6809
7169
  const triggerExpandNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-table--expanded').flag;
7170
+ const triggerRowGroupNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-row-group--node-btn').flag;
6810
7171
  params = Object.assign({ cell, triggerRadio, triggerCheckbox, triggerTreeNode, triggerExpandNode }, params);
6811
7172
  if (!triggerCheckbox && !triggerRadio) {
6812
7173
  // 如果是展开行
@@ -6817,11 +7178,15 @@ const Methods = {
6817
7178
  if ((treeOpts.trigger === 'row' || (treeNode && treeOpts.trigger === 'cell'))) {
6818
7179
  $xeTable.triggerTreeExpandEvent(evnt, params);
6819
7180
  }
7181
+ // 如果是行分组
7182
+ if ((rowGroupOpts.trigger === 'row' || (rowGroupNode && rowGroupOpts.trigger === 'cell'))) {
7183
+ $xeTable.triggerRowGroupExpandEvent(evnt, params);
7184
+ }
6820
7185
  }
6821
7186
  // 如果点击了树节点
6822
7187
  if (!triggerTreeNode) {
6823
- if (!triggerExpandNode) {
6824
- // 如果是高亮行
7188
+ if (!triggerExpandNode && !triggerRowGroupNode) {
7189
+ // 如果是当前行
6825
7190
  if (rowOpts.isCurrent || highlightCurrentRow) {
6826
7191
  if (!triggerCheckbox && !triggerRadio) {
6827
7192
  $xeTable.triggerCurrentRowEvent(evnt, params);
@@ -7033,7 +7398,7 @@ const Methods = {
7033
7398
  const triggerInput = cell && cell.tagName && cell.tagName.toLowerCase() === 'input';
7034
7399
  const triggerRadio = isRadioType && getEventTargetNode(evnt, cell, 'vxe-cell--radio').flag;
7035
7400
  const triggerCheckbox = isCheckboxType && getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
7036
- const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-tree--btn-wrapper').flag;
7401
+ const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-cell--tree-btn').flag;
7037
7402
  const triggerExpandNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-table--expanded').flag;
7038
7403
  let isColDragCell = false;
7039
7404
  if (rowOpts.drag) {
@@ -7307,7 +7672,7 @@ const Methods = {
7307
7672
  evnt.preventDefault();
7308
7673
  return;
7309
7674
  }
7310
- const hasCtrlKey = evnt.ctrlKey;
7675
+ const isControlKey = hasControlKey(evnt);
7311
7676
  const trEl = evnt.currentTarget;
7312
7677
  const rowid = trEl.getAttribute('rowid') || '';
7313
7678
  const rest = fullAllDataRowIdData[rowid];
@@ -7319,11 +7684,11 @@ const Methods = {
7319
7684
  const { dragRow } = reactData;
7320
7685
  const offsetY = evnt.clientY - trEl.getBoundingClientRect().y;
7321
7686
  const dragPos = offsetY < trEl.clientHeight / 2 ? 'top' : 'bottom';
7322
- internalData.prevDragToChild = !!(treeConfig && transform && isToChildDrag && hasCtrlKey);
7687
+ internalData.prevDragToChild = !!(treeConfig && transform && isToChildDrag && isControlKey);
7323
7688
  internalData.prevDragRow = row;
7324
7689
  internalData.prevDragPos = dragPos;
7325
7690
  if ($xeTable.eqRow(dragRow, row) ||
7326
- (hasCtrlKey && treeConfig && lazy && row[hasChildField] && rowRest && !rowRest.treeLoaded) ||
7691
+ (isControlKey && treeConfig && lazy && row[hasChildField] && rowRest && !rowRest.treeLoaded) ||
7327
7692
  (!isCrossDrag && treeConfig && transform && (isPeerDrag ? dragRow[parentField] !== row[parentField] : rest.level))) {
7328
7693
  showDropTip($xeTable, evnt, trEl, null, false, dragPos);
7329
7694
  return;
@@ -7588,7 +7953,7 @@ const Methods = {
7588
7953
  evnt.preventDefault();
7589
7954
  return;
7590
7955
  }
7591
- const hasCtrlKey = evnt.ctrlKey;
7956
+ const isControlKey = hasControlKey(evnt);
7592
7957
  const thEl = evnt.currentTarget;
7593
7958
  const colid = thEl.getAttribute('colid');
7594
7959
  const column = $xeTable.getColumnById(colid);
@@ -7597,7 +7962,7 @@ const Methods = {
7597
7962
  const { clientX } = evnt;
7598
7963
  const offsetX = clientX - thEl.getBoundingClientRect().x;
7599
7964
  const dragPos = offsetX < thEl.clientWidth / 2 ? 'left' : 'right';
7600
- internalData.prevDragToChild = !!((isCrossDrag && isToChildDrag) && hasCtrlKey);
7965
+ internalData.prevDragToChild = !!((isCrossDrag && isToChildDrag) && isControlKey);
7601
7966
  internalData.prevDragCol = column;
7602
7967
  internalData.prevDragPos = dragPos;
7603
7968
  if (column.fixed ||
@@ -8001,7 +8366,7 @@ const Methods = {
8001
8366
  const $xeTable = this;
8002
8367
  const reactData = $xeTable;
8003
8368
  const internalData = $xeTable;
8004
- const { expandColumn: column } = reactData;
8369
+ const { expandColumn } = reactData;
8005
8370
  const { rowExpandLazyLoadedMaps } = internalData;
8006
8371
  const expandOpts = $xeTable.computeExpandOpts;
8007
8372
  const { row } = params;
@@ -8013,12 +8378,12 @@ const Methods = {
8013
8378
  const rowid = getRowid($xeTable, row);
8014
8379
  if (!lazy || !rowExpandLazyLoadedMaps[rowid]) {
8015
8380
  const expanded = !$xeTable.isRowExpandByRow(row);
8016
- const columnIndex = $xeTable.getColumnIndex(column);
8017
- const $columnIndex = $xeTable.getVMColumnIndex(column);
8381
+ const columnIndex = expandColumn ? $xeTable.getColumnIndex(expandColumn) : -1;
8382
+ const $columnIndex = expandColumn ? $xeTable.getVMColumnIndex(expandColumn) : -1;
8018
8383
  $xeTable.setRowExpand(row, expanded);
8019
8384
  $xeTable.dispatchEvent('toggle-row-expand', {
8020
8385
  expanded,
8021
- column,
8386
+ column: expandColumn,
8022
8387
  columnIndex,
8023
8388
  $columnIndex,
8024
8389
  row,
@@ -8068,8 +8433,8 @@ const Methods = {
8068
8433
  const expandOpts = $xeTable.computeExpandOpts;
8069
8434
  const { reserve, lazy, accordion, toggleMethod } = expandOpts;
8070
8435
  const lazyRests = [];
8071
- const columnIndex = $xeTable.getColumnIndex(expandColumn);
8072
- const $columnIndex = $xeTable.getVMColumnIndex(expandColumn);
8436
+ const columnIndex = expandColumn ? $xeTable.getColumnIndex(expandColumn) : -1;
8437
+ const $columnIndex = expandColumn ? $xeTable.getVMColumnIndex(expandColumn) : -1;
8073
8438
  if (rows) {
8074
8439
  if (!XEUtils.isArray(rows)) {
8075
8440
  rows = [rows];
@@ -8181,6 +8546,88 @@ const Methods = {
8181
8546
  });
8182
8547
  return rest;
8183
8548
  },
8549
+ setRowGroups(fieldOrColumns) {
8550
+ const $xeTable = this;
8551
+ const props = $xeTable;
8552
+ const internalData = $xeTable;
8553
+ const { rowGroupConfig } = props;
8554
+ if (!rowGroupConfig) {
8555
+ errLog('vxe.error.reqProp', ['row-group-config']);
8556
+ return $xeTable.$nextTick();
8557
+ }
8558
+ if (fieldOrColumns) {
8559
+ handleUpdateRowGroup($xeTable, (XEUtils.isArray(fieldOrColumns) ? fieldOrColumns : [fieldOrColumns]).map(fieldOrColumn => {
8560
+ return XEUtils.isString(fieldOrColumn) ? fieldOrColumn : fieldOrColumn.field;
8561
+ }));
8562
+ return loadTableData($xeTable, internalData.tableSynchData, true);
8563
+ }
8564
+ return $xeTable.$nextTick();
8565
+ },
8566
+ clearRowGroups() {
8567
+ const $xeTable = this;
8568
+ const props = $xeTable;
8569
+ const internalData = $xeTable;
8570
+ const { rowGroupConfig } = props;
8571
+ if (!rowGroupConfig) {
8572
+ errLog('vxe.error.reqProp', ['row-group-config']);
8573
+ return $xeTable.$nextTick();
8574
+ }
8575
+ handleUpdateRowGroup($xeTable, []);
8576
+ return loadTableData($xeTable, internalData.tableSynchData, true);
8577
+ },
8578
+ isRowGroupRecord(row) {
8579
+ const $xeTable = this;
8580
+ const reactData = $xeTable;
8581
+ const { isRowGroupStatus } = reactData;
8582
+ return isRowGroupStatus && row.isAggregate;
8583
+ },
8584
+ isRowGroupExpandByRow(row) {
8585
+ const $xeTable = this;
8586
+ const reactData = $xeTable;
8587
+ const internalData = $xeTable;
8588
+ const { rowGroupExpandedFlag } = reactData;
8589
+ const { rowGroupExpandedMaps } = internalData;
8590
+ return !!rowGroupExpandedFlag && !!rowGroupExpandedMaps[getRowid($xeTable, row)];
8591
+ },
8592
+ setRowGroupExpand(rows, expanded) {
8593
+ const $xeTable = this;
8594
+ if (rows) {
8595
+ if (!XEUtils.isArray(rows)) {
8596
+ rows = [rows];
8597
+ }
8598
+ return handleRowGroupVirtualExpand($xeTable, rows, expanded);
8599
+ }
8600
+ return $xeTable.$nextTick();
8601
+ },
8602
+ setAllRowGroupExpand(expanded) {
8603
+ const $xeTable = this;
8604
+ const reactData = $xeTable;
8605
+ const internalData = $xeTable;
8606
+ const { tableFullGroupData } = internalData;
8607
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
8608
+ const { mapChildrenField } = rowGroupOpts;
8609
+ const rgExpandedMaps = {};
8610
+ if (expanded && mapChildrenField) {
8611
+ XEUtils.eachTree(tableFullGroupData, (row) => {
8612
+ if (row[mapChildrenField] && row[mapChildrenField].length) {
8613
+ rgExpandedMaps[getRowid($xeTable, row)] = row;
8614
+ }
8615
+ }, { children: mapChildrenField });
8616
+ }
8617
+ internalData.rowGroupExpandedMaps = rgExpandedMaps;
8618
+ handleVirtualTreeToList($xeTable);
8619
+ reactData.rowGroupExpandedFlag++;
8620
+ return $xeTable.handleTableData();
8621
+ },
8622
+ clearRowGroupExpand() {
8623
+ const $xeTable = this;
8624
+ const reactData = $xeTable;
8625
+ const internalData = $xeTable;
8626
+ internalData.rowGroupExpandedMaps = {};
8627
+ handleVirtualTreeToList($xeTable);
8628
+ reactData.rowGroupExpandedFlag++;
8629
+ return $xeTable.handleTableData();
8630
+ },
8184
8631
  getTreeExpandRecords() {
8185
8632
  const $xeTable = this;
8186
8633
  const internalData = $xeTable;
@@ -8242,11 +8689,11 @@ const Methods = {
8242
8689
  });
8243
8690
  }
8244
8691
  internalData.treeExpandedMaps = {};
8245
- reactData.treeExpandedFlag++;
8246
8692
  if (transform) {
8247
8693
  handleVirtualTreeToList($xeTable);
8248
- return $xeTable.handleTableData();
8694
+ $xeTable.handleTableData();
8249
8695
  }
8696
+ reactData.treeExpandedFlag++;
8250
8697
  return $xeTable.$nextTick();
8251
8698
  },
8252
8699
  /**
@@ -8255,6 +8702,7 @@ const Methods = {
8255
8702
  */
8256
8703
  reloadTreeExpand(row) {
8257
8704
  const $xeTable = this;
8705
+ const reactData = $xeTable;
8258
8706
  const internalData = $xeTable;
8259
8707
  const { treeExpandLazyLoadedMaps } = internalData;
8260
8708
  const treeOpts = $xeTable.computeTreeOpts;
@@ -8267,8 +8715,9 @@ const Methods = {
8267
8715
  }).then(() => {
8268
8716
  if (transform) {
8269
8717
  handleVirtualTreeToList($xeTable);
8270
- return $xeTable.handleTableData();
8718
+ $xeTable.handleTableData();
8271
8719
  }
8720
+ reactData.treeExpandedFlag++;
8272
8721
  }).then(() => {
8273
8722
  return $xeTable.recalculate();
8274
8723
  });
@@ -8283,6 +8732,27 @@ const Methods = {
8283
8732
  // 即将废弃
8284
8733
  return $xeTable.reloadTreeExpand(row);
8285
8734
  },
8735
+ /**
8736
+ * 行分组事件
8737
+ */
8738
+ triggerRowGroupExpandEvent(evnt, params) {
8739
+ const $xeTable = this;
8740
+ const internalData = $xeTable;
8741
+ const { rowGroupExpandedMaps } = internalData;
8742
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
8743
+ const { row, column } = params;
8744
+ const { trigger } = rowGroupOpts;
8745
+ if (trigger === 'manual') {
8746
+ return;
8747
+ }
8748
+ evnt.stopPropagation();
8749
+ const rowid = getRowid($xeTable, row);
8750
+ const expanded = !rowGroupExpandedMaps[rowid];
8751
+ const columnIndex = $xeTable.getColumnIndex(column);
8752
+ const $columnIndex = $xeTable.getVMColumnIndex(column);
8753
+ $xeTable.setRowGroupExpand(row, expanded);
8754
+ $xeTable.dispatchEvent('toggle-row-group-expand', { expanded, column, columnIndex, $columnIndex, row }, evnt);
8755
+ },
8286
8756
  /**
8287
8757
  * 展开树节点事件
8288
8758
  */
@@ -8327,8 +8797,12 @@ const Methods = {
8327
8797
  * @param {Boolean} expanded 是否展开
8328
8798
  */
8329
8799
  setAllTreeExpand(expanded) {
8330
- const { tableFullData, treeOpts } = this;
8331
- const { lazy } = treeOpts;
8800
+ const $xeTable = this;
8801
+ const reactData = $xeTable;
8802
+ const internalData = $xeTable;
8803
+ const { tableFullData } = internalData;
8804
+ const treeOpts = $xeTable.computeTreeOpts;
8805
+ const { transform, lazy } = treeOpts;
8332
8806
  const childrenField = treeOpts.children || treeOpts.childrenField;
8333
8807
  const expandeds = [];
8334
8808
  XEUtils.eachTree(tableFullData, (row) => {
@@ -8337,7 +8811,13 @@ const Methods = {
8337
8811
  expandeds.push(row);
8338
8812
  }
8339
8813
  }, { children: childrenField });
8340
- return this.setTreeExpand(expandeds, expanded);
8814
+ return $xeTable.setTreeExpand(expandeds, expanded).then(() => {
8815
+ if (transform) {
8816
+ handleVirtualTreeToList($xeTable);
8817
+ reactData.treeExpandedFlag++;
8818
+ return $xeTable.recalculate();
8819
+ }
8820
+ });
8341
8821
  },
8342
8822
  /**
8343
8823
  * 设置展开树形节点,二个参数设置这一行展开与否
@@ -8391,15 +8871,15 @@ const Methods = {
8391
8871
  const { transform, reserve } = treeOpts;
8392
8872
  const expList = $xeTable.getTreeExpandRecords();
8393
8873
  internalData.treeExpandedMaps = {};
8394
- reactData.treeExpandedFlag++;
8395
8874
  if (reserve) {
8396
8875
  XEUtils.eachTree(tableFullTreeData, row => handleTreeExpandReserve($xeTable, row, false), { children: childrenField });
8397
8876
  }
8398
8877
  return $xeTable.handleTableData().then(() => {
8399
8878
  if (transform) {
8400
8879
  handleVirtualTreeToList($xeTable);
8401
- return $xeTable.handleTableData();
8880
+ $xeTable.handleTableData();
8402
8881
  }
8882
+ reactData.treeExpandedFlag++;
8403
8883
  }).then(() => {
8404
8884
  if (expList.length) {
8405
8885
  $xeTable.recalculate();
@@ -9184,21 +9664,29 @@ const Methods = {
9184
9664
  * @param {Row} row 行对象
9185
9665
  */
9186
9666
  scrollToTreeRow(row) {
9187
- const { tableFullData, treeConfig, treeOpts } = this;
9188
- const childrenField = treeOpts.children || treeOpts.childrenField;
9667
+ const $xeTable = this;
9668
+ const props = $xeTable;
9669
+ const reactData = $xeTable;
9670
+ const internalData = $xeTable;
9671
+ const { treeConfig } = props;
9672
+ const { isRowGroupStatus } = reactData;
9673
+ const { tableFullData } = internalData;
9189
9674
  const rests = [];
9190
- if (treeConfig) {
9191
- const matchObj = XEUtils.findTree(tableFullData, item => item === row, { children: childrenField });
9675
+ if (treeConfig || isRowGroupStatus) {
9676
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
9677
+ const treeOpts = $xeTable.computeTreeOpts;
9678
+ const childrenField = treeOpts.children || treeOpts.childrenField;
9679
+ const matchObj = XEUtils.findTree(tableFullData, item => $xeTable.eqRow(item, row), { children: isRowGroupStatus ? rowGroupOpts.mapChildrenField : childrenField });
9192
9680
  if (matchObj) {
9193
9681
  const nodes = matchObj.nodes;
9194
9682
  nodes.forEach((row, index) => {
9195
- if (index < nodes.length - 1 && !this.isTreeExpandByRow(row)) {
9196
- rests.push(this.setTreeExpand(row, true));
9683
+ if (index < nodes.length - 1 && !$xeTable.isTreeExpandByRow(row)) {
9684
+ rests.push($xeTable.setTreeExpand(row, true));
9197
9685
  }
9198
9686
  });
9199
9687
  }
9200
9688
  }
9201
- return Promise.all(rests).then(() => rowToVisible(this, row));
9689
+ return Promise.all(rests).then(() => rowToVisible($xeTable, row));
9202
9690
  },
9203
9691
  /**
9204
9692
  * 手动清除滚动相关信息,还原到初始状态