vxe-table 3.15.5 → 3.15.6

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 +977 -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 +1729 -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 +1158 -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 +1010 -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.1745197894601.ttf} +0 -0
  167. /package/es/{iconfont.1744880837792.woff → iconfont.1745197894601.woff} +0 -0
  168. /package/es/{iconfont.1744880837792.woff2 → iconfont.1745197894601.woff2} +0 -0
  169. /package/lib/{iconfont.1744880837792.ttf → iconfont.1745197894601.ttf} +0 -0
  170. /package/lib/{iconfont.1744880837792.woff → iconfont.1745197894601.woff} +0 -0
  171. /package/lib/{iconfont.1744880837792.woff2 → iconfont.1745197894601.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,259 @@ 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.insertRowMaps = {};
2623
+ internalData.removeRowMaps = {};
2624
+ const sYLoad = updateScrollYStatus($xeTable, fullData);
2625
+ reactData.isDragColMove = false;
2626
+ reactData.isDragRowMove = false;
2627
+ // 全量数据
2628
+ internalData.tableFullData = fullData;
2629
+ internalData.tableFullTreeData = isRGroup ? [] : treeData;
2630
+ internalData.tableFullGroupData = isRGroup ? treeData : [];
2631
+ // 缓存数据
2632
+ $xeTable.cacheRowMap(isReset);
2633
+ // 原始数据
2634
+ internalData.tableSynchData = datas;
2635
+ if (isReset) {
2636
+ internalData.isResizeCellHeight = false;
2637
+ }
2638
+ // 克隆原数据,用于显示编辑状态,与编辑值做对比
2639
+ if (keepSource) {
2640
+ $xeTable.cacheSourceMap(fullData);
2641
+ }
2642
+ if ($xeTable.clearCellAreas && props.mouseConfig) {
2643
+ $xeTable.clearCellAreas();
2644
+ $xeTable.clearCopyCellArea();
2645
+ }
2646
+ $xeTable.clearMergeCells();
2647
+ $xeTable.clearMergeFooterItems();
2648
+ $xeTable.handleTableData(true);
2649
+ $xeTable.updateFooter();
2650
+ $xeTable.handleUpdateBodyMerge();
2651
+ return $xeTable.$nextTick().then(() => {
2652
+ updateHeight($xeTable);
2653
+ updateStyle($xeTable);
2654
+ }).then(() => {
2655
+ computeScrollLoad($xeTable);
2656
+ }).then(() => {
2657
+ // 是否启用了虚拟滚动
2658
+ if (sYLoad) {
2659
+ scrollYStore.endIndex = scrollYStore.visibleSize;
2660
+ }
2661
+ if (sYLoad) {
2662
+ if (reactData.expandColumn && expandOpts.mode !== 'fixed') {
2663
+ errLog('vxe.error.notConflictProp', ['column.type="expand', 'expand-config.mode="fixed"']);
2664
+ }
2665
+ // if (showOverflow) {
2666
+ // if (!rowOpts.height) {
2667
+ // const errColumn = internalData.tableFullColumn.find(column => column.showOverflow === false)
2668
+ // if (errColumn) {
2669
+ // errLog('vxe.error.errProp', [`column[field="${errColumn.field}"].show-overflow=false`, 'show-overflow=true'])
2670
+ // }
2671
+ // }
2672
+ // }
2673
+ if (!(props.height || props.maxHeight)) {
2674
+ errLog('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}']);
2675
+ }
2676
+ // if (!props.showOverflow) {
2677
+ // warnLog('vxe.error.reqProp', ['table.show-overflow'])
2678
+ // }
2679
+ if (props.spanMethod) {
2680
+ errLog('vxe.error.scrollErrProp', ['table.span-method']);
2681
+ }
2682
+ }
2683
+ handleReserveStatus($xeTable);
2684
+ $xeTable.checkSelectionStatus();
2685
+ return new Promise(resolve => {
2686
+ $xeTable.$nextTick()
2687
+ .then(() => handleRecalculateLayout($xeTable, false))
2688
+ .then(() => {
2689
+ calcCellHeight($xeTable);
2690
+ updateRowOffsetTop($xeTable);
2691
+ return handleRecalculateLayout($xeTable, false);
2692
+ })
2693
+ .then(() => {
2694
+ let targetScrollLeft = lastScrollLeft;
2695
+ let targetScrollTop = lastScrollTop;
2696
+ const virtualXOpts = $xeTable.computeVirtualXOpts;
2697
+ const virtualYOpts = $xeTable.computeVirtualYOpts;
2698
+ // 是否在更新数据之后自动滚动重置滚动条
2699
+ if (virtualXOpts.scrollToLeftOnChange) {
2700
+ targetScrollLeft = 0;
2701
+ }
2702
+ if (virtualYOpts.scrollToTopOnChange) {
2703
+ targetScrollTop = 0;
2704
+ }
2705
+ reactData.isRowLoading = false;
2706
+ handleRecalculateLayout($xeTable, false);
2707
+ // 是否变更虚拟滚动
2708
+ if (oldScrollYLoad === sYLoad) {
2709
+ restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
2710
+ .then(() => {
2711
+ resolve();
2712
+ });
2713
+ }
2714
+ else {
2715
+ setTimeout(() => {
2716
+ restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
2717
+ .then(() => {
2718
+ resolve();
2719
+ });
2720
+ });
2721
+ }
2722
+ });
2723
+ });
2724
+ });
2725
+ }
2108
2726
  /**
2109
2727
  * 处理数据加载默认行为
2110
2728
  * 默认执行一次,除非被重置
@@ -2768,16 +3386,23 @@ const Methods = {
2768
3386
  clearAll() {
2769
3387
  return clearTableAllStatus(this);
2770
3388
  },
3389
+ handleUpdateRowGroup(groupFields) {
3390
+ const $xeTable = this;
3391
+ handleUpdateRowGroup($xeTable, groupFields);
3392
+ },
2771
3393
  /**
2772
3394
  * 同步 data 数据(即将废弃)
2773
3395
  * 如果用了该方法,那么组件将不再记录增删改的状态,只能自行实现对应逻辑
2774
3396
  * 对于某些特殊的场景,比如深层树节点元素发生变动时可能会用到
2775
3397
  */
2776
3398
  syncData() {
3399
+ const $xeTable = this;
3400
+ const reactData = $xeTable;
3401
+ const internalData = $xeTable;
2777
3402
  errLog('vxe.error.delFunc', ['syncData', 'getData']);
2778
- return this.$nextTick().then(() => {
2779
- this.tableData = [];
2780
- return this.$nextTick().then(() => this.loadTableData(this.tableFullData, true));
3403
+ return $xeTable.$nextTick().then(() => {
3404
+ reactData.tableData = [];
3405
+ return $xeTable.$nextTick().then(() => loadTableData($xeTable, internalData.tableFullData, true));
2781
3406
  });
2782
3407
  },
2783
3408
  /**
@@ -2800,205 +3425,48 @@ const Methods = {
2800
3425
  return $xeTable.refreshScroll();
2801
3426
  }
2802
3427
  }).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);
3428
+ $xeTable.updateCellAreas();
3429
+ return $xeTable.recalculate(true);
2933
3430
  }).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
- });
3431
+ // 存在滚动行为未结束情况
3432
+ setTimeout(() => $xeTable.recalculate(), 50);
3433
+ });
3434
+ },
3435
+ handleTableData(force) {
3436
+ const $xeTable = this;
3437
+ const reactData = $xeTable;
3438
+ const internalData = $xeTable;
3439
+ const { scrollYLoad } = reactData;
3440
+ const { scrollYStore, fullDataRowIdData } = internalData;
3441
+ let fullList = internalData.afterFullData;
3442
+ // 是否进行数据处理
3443
+ if (force) {
3444
+ // 更新数据,处理筛选和排序
3445
+ updateAfterFullData($xeTable);
3446
+ // 如果为虚拟树,将树结构拍平
3447
+ fullList = handleVirtualTreeToList($xeTable);
3448
+ }
3449
+ const tableData = scrollYLoad ? fullList.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullList.slice(0);
3450
+ const visibleDataRowIdMaps = {};
3451
+ tableData.forEach((row, $index) => {
3452
+ const rowid = getRowid($xeTable, row);
3453
+ const rest = fullDataRowIdData[rowid];
3454
+ if (rest) {
3455
+ rest.$index = $index;
3456
+ }
3457
+ visibleDataRowIdMaps[rowid] = row;
3001
3458
  });
3459
+ reactData.tableData = tableData;
3460
+ internalData.visibleDataRowIdData = visibleDataRowIdMaps;
3461
+ return $xeTable.$nextTick();
3462
+ },
3463
+ /**
3464
+ * 加载表格数据
3465
+ * @param {Array} datas 数据
3466
+ */
3467
+ loadTableData(datas, isReset) {
3468
+ const $xeTable = this;
3469
+ return loadTableData($xeTable, datas, isReset);
3002
3470
  },
3003
3471
  /**
3004
3472
  * 重新加载数据,不会清空表格状态
@@ -3007,7 +3475,7 @@ const Methods = {
3007
3475
  loadData(datas) {
3008
3476
  const $xeTable = this;
3009
3477
  const { initStatus } = this;
3010
- return this.loadTableData(datas, false).then(() => {
3478
+ return loadTableData($xeTable, datas, false).then(() => {
3011
3479
  this.inited = true;
3012
3480
  this.initStatus = true;
3013
3481
  if (!initStatus) {
@@ -3026,7 +3494,7 @@ const Methods = {
3026
3494
  .then(() => {
3027
3495
  this.inited = true;
3028
3496
  this.initStatus = true;
3029
- return this.loadTableData(datas, true);
3497
+ return loadTableData($xeTable, datas, true);
3030
3498
  })
3031
3499
  .then(() => {
3032
3500
  handleLoadDefaults($xeTable);
@@ -3111,11 +3579,8 @@ const Methods = {
3111
3579
  const reactData = $xeTable;
3112
3580
  const internalData = $xeTable;
3113
3581
  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;
3582
+ const { isRowGroupStatus } = reactData;
3583
+ const { fullAllDataRowIdData, tableFullData, tableFullTreeData, tableFullGroupData, treeExpandedMaps } = internalData;
3119
3584
  const fullAllDataRowIdMaps = isReset ? {} : Object.assign({}, fullAllDataRowIdData); // 存在已删除数据
3120
3585
  const fullDataRowIdMaps = {};
3121
3586
  const { handleUpdateRowId } = createHandleUpdateRowId($xeTable);
@@ -3136,6 +3601,10 @@ const Methods = {
3136
3601
  fullAllDataRowIdMaps[rowid] = rowRest;
3137
3602
  };
3138
3603
  if (treeConfig) {
3604
+ const treeOpts = $xeTable.computeTreeOpts;
3605
+ const { lazy } = treeOpts;
3606
+ const childrenField = treeOpts.children || treeOpts.childrenField;
3607
+ const hasChildField = treeOpts.hasChild || treeOpts.hasChildField;
3139
3608
  XEUtils.eachTree(tableFullTreeData, (row, index, items, path, parentRow, nodes) => {
3140
3609
  const rowid = handleUpdateRowId(row);
3141
3610
  if (treeConfig && lazy) {
@@ -3151,6 +3620,14 @@ const Methods = {
3151
3620
  handleRowCache(row, index, items, parentRow ? -1 : index, parentRow, rowid, nodes.length - 1, toTreePathSeq(path));
3152
3621
  }, { children: childrenField });
3153
3622
  }
3623
+ else if (isRowGroupStatus) {
3624
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
3625
+ const { mapChildrenField } = rowGroupOpts;
3626
+ XEUtils.eachTree(tableFullGroupData, (row, index, items, path, parentRow, nodes) => {
3627
+ const rowid = handleUpdateRowId(row);
3628
+ handleRowCache(row, index, items, parentRow ? -1 : index, parentRow, rowid, nodes.length - 1, toTreePathSeq(path));
3629
+ }, { children: mapChildrenField });
3630
+ }
3154
3631
  else {
3155
3632
  tableFullData.forEach((row, index, items) => {
3156
3633
  handleRowCache(row, index, items, index, null, handleUpdateRowId(row), 0, index + 1);
@@ -3893,174 +4370,6 @@ const Methods = {
3893
4370
  }
3894
4371
  return rowList;
3895
4372
  },
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
4373
  /**
4065
4374
  * 预编译
4066
4375
  * 对渲染中的数据提前解析序号及索引。牺牲提前编译耗时换取渲染中额外损耗,使运行时更加流畅
@@ -4401,7 +4710,7 @@ const Methods = {
4401
4710
  }
4402
4711
  const storeData = getCustomStorageMap(tableId);
4403
4712
  if (restoreStore) {
4404
- return Promise.resolve(restoreStore({ id: tableId, type: 'restore', storeData })).then(storeData => {
4713
+ return Promise.resolve(restoreStore({ $table: $xeTable, id: tableId, type: 'restore', storeData })).then(storeData => {
4405
4714
  if (!storeData) {
4406
4715
  return;
4407
4716
  }
@@ -4466,7 +4775,7 @@ const Methods = {
4466
4775
  hasResizable = 1;
4467
4776
  resizableData[colKey] = column.renderWidth;
4468
4777
  }
4469
- if (isCustomVisible && (!checkMethod || checkMethod({ column }))) {
4778
+ if (isCustomVisible && (!checkMethod || checkMethod({ $table: $xeTable, column }))) {
4470
4779
  if (!column.visible && column.defaultVisible) {
4471
4780
  hasVisible = 1;
4472
4781
  visibleData[colKey] = false;
@@ -4523,6 +4832,7 @@ const Methods = {
4523
4832
  : this.getCustomStoreData();
4524
4833
  if (updateStore) {
4525
4834
  return updateStore({
4835
+ $table: $xeTable,
4526
4836
  id: tableId,
4527
4837
  type,
4528
4838
  storeData
@@ -5400,8 +5710,7 @@ const Methods = {
5400
5710
  const hasDeleteKey = keyCode === 46;
5401
5711
  const isF2 = keyCode === 113;
5402
5712
  const isContextMenu = keyCode === 93;
5403
- const hasMetaKey = evnt.metaKey;
5404
- const hasCtrlKey = evnt.ctrlKey;
5713
+ const isControlKey = hasControlKey(evnt);
5405
5714
  const hasShiftKey = evnt.shiftKey;
5406
5715
  const hasAltKey = evnt.altKey;
5407
5716
  const operArrow = isLeftArrow || isUpArrow || isRightArrow || isDwArrow;
@@ -5471,7 +5780,7 @@ const Methods = {
5471
5780
  else if (isEnter && !hasAltKey && keyboardConfig && keyboardOpts.isEnter && (selected.row || actived.row || (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow))) {
5472
5781
  const { isLastEnterAppendRow, beforeEnterMethod, enterMethod } = keyboardOpts;
5473
5782
  // 退出选中
5474
- if (hasCtrlKey) {
5783
+ if (isControlKey) {
5475
5784
  // 如果是激活编辑状态,则取消编辑
5476
5785
  if (actived.row) {
5477
5786
  const params = actived.args;
@@ -5652,7 +5961,7 @@ const Methods = {
5652
5961
  .then(() => $xeTable.triggerCurrentRowEvent(evnt, params));
5653
5962
  }
5654
5963
  }
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))) {
5964
+ 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
5965
  const { editMethod } = keyboardOpts;
5657
5966
  // 启用编辑后,空格键功能将失效
5658
5967
  // if (isSpacebar) {
@@ -6015,7 +6324,9 @@ const Methods = {
6015
6324
  const reactData = $xeTable;
6016
6325
  const internalData = $xeTable;
6017
6326
  const { treeConfig } = props;
6327
+ const { isRowGroupStatus } = reactData;
6018
6328
  const { selectCheckboxMaps } = internalData;
6329
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
6019
6330
  const treeOpts = $xeTable.computeTreeOpts;
6020
6331
  const { transform, mapChildrenField } = treeOpts;
6021
6332
  const childrenField = treeOpts.children || treeOpts.childrenField;
@@ -6026,10 +6337,10 @@ const Methods = {
6026
6337
  const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField;
6027
6338
  if (checkField) {
6028
6339
  // 树结构
6029
- if (treeConfig && !checkStrictly) {
6340
+ if ((treeConfig || isRowGroupStatus) && !checkStrictly) {
6030
6341
  // 更新子节点状态
6031
6342
  XEUtils.eachTree(rows, (row) => {
6032
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6343
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6033
6344
  XEUtils.set(row, checkField, checked);
6034
6345
  if (indeterminateField) {
6035
6346
  XEUtils.set(row, indeterminateField, false);
@@ -6042,7 +6353,7 @@ const Methods = {
6042
6353
  }
6043
6354
  // 列表
6044
6355
  rows.forEach(row => {
6045
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6356
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6046
6357
  XEUtils.set(row, checkField, checked);
6047
6358
  handleCheckboxReserveRow($xeTable, row, checked);
6048
6359
  }
@@ -6051,29 +6362,50 @@ const Methods = {
6051
6362
  return;
6052
6363
  }
6053
6364
  // 树结构
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;
6365
+ if (!checkStrictly) {
6366
+ if (isRowGroupStatus) {
6367
+ // 更新行分组节点状态
6368
+ XEUtils.eachTree(rows, (row) => {
6369
+ const rowid = handleGetRowId(row);
6370
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6371
+ if (checked) {
6372
+ selectCheckboxMaps[rowid] = row;
6373
+ }
6374
+ else {
6375
+ if (selectCheckboxMaps[rowid]) {
6376
+ delete selectCheckboxMaps[rowid];
6377
+ }
6378
+ }
6379
+ handleCheckboxReserveRow($xeTable, row, checked);
6061
6380
  }
6062
- else {
6063
- if (selectCheckboxMaps[rowid]) {
6064
- delete selectCheckboxMaps[rowid];
6381
+ }, { children: rowGroupOpts.mapChildrenField });
6382
+ reactData.updateCheckboxFlag++;
6383
+ return;
6384
+ }
6385
+ else if (treeConfig) {
6386
+ // 更新子节点状态
6387
+ XEUtils.eachTree(rows, (row) => {
6388
+ const rowid = handleGetRowId(row);
6389
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6390
+ if (checked) {
6391
+ selectCheckboxMaps[rowid] = row;
6392
+ }
6393
+ else {
6394
+ if (selectCheckboxMaps[rowid]) {
6395
+ delete selectCheckboxMaps[rowid];
6396
+ }
6065
6397
  }
6398
+ handleCheckboxReserveRow($xeTable, row, checked);
6066
6399
  }
6067
- handleCheckboxReserveRow($xeTable, row, checked);
6068
- }
6069
- }, { children: transform ? mapChildrenField : childrenField });
6070
- reactData.updateCheckboxFlag++;
6071
- return;
6400
+ }, { children: transform ? mapChildrenField : childrenField });
6401
+ reactData.updateCheckboxFlag++;
6402
+ return;
6403
+ }
6072
6404
  }
6073
6405
  // 列表
6074
6406
  rows.forEach(row => {
6075
6407
  const rowid = handleGetRowId(row);
6076
- if (isForce || (!checkMethod || checkMethod({ row }))) {
6408
+ if (isForce || (!checkMethod || checkMethod({ $table: $xeTable, row }))) {
6077
6409
  if (checked) {
6078
6410
  if (!selectCheckboxMaps[rowid]) {
6079
6411
  selectCheckboxMaps[rowid] = row;
@@ -6125,8 +6457,11 @@ const Methods = {
6125
6457
  triggerCheckRowEvent(evnt, params, checked) {
6126
6458
  const $xeTable = this;
6127
6459
  const props = $xeTable;
6460
+ const reactData = $xeTable;
6128
6461
  const internalData = $xeTable;
6462
+ const { treeConfig } = props;
6129
6463
  const { row } = params;
6464
+ const { isRowGroupStatus } = reactData;
6130
6465
  const { afterFullData } = internalData;
6131
6466
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6132
6467
  const { checkMethod, trigger } = checkboxOpts;
@@ -6134,7 +6469,7 @@ const Methods = {
6134
6469
  return;
6135
6470
  }
6136
6471
  evnt.stopPropagation();
6137
- if (checkboxOpts.isShiftKey && evnt.shiftKey && !props.treeConfig) {
6472
+ if (checkboxOpts.isShiftKey && evnt.shiftKey && !(treeConfig || isRowGroupStatus)) {
6138
6473
  const checkboxRecords = $xeTable.getCheckboxRecords();
6139
6474
  if (checkboxRecords.length) {
6140
6475
  const firstRow = checkboxRecords[0];
@@ -6151,7 +6486,7 @@ const Methods = {
6151
6486
  }
6152
6487
  }
6153
6488
  }
6154
- if (!checkMethod || checkMethod({ row })) {
6489
+ if (!checkMethod || checkMethod({ $table: $xeTable, row })) {
6155
6490
  $xeTable.handleBatchSelectRows([row], checked);
6156
6491
  $xeTable.checkSelectionStatus();
6157
6492
  $xeTable.dispatchEvent('checkbox-change', Object.assign({
@@ -6190,29 +6525,46 @@ const Methods = {
6190
6525
  const reactData = $xeTable;
6191
6526
  const internalData = $xeTable;
6192
6527
  const { treeConfig } = props;
6193
- const { selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6528
+ const { isRowGroupStatus } = reactData;
6529
+ const { afterTreeFullData, afterGroupFullData, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6530
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
6194
6531
  const treeOpts = $xeTable.computeTreeOpts;
6195
- const { transform, mapChildrenField } = treeOpts;
6196
6532
  const childrenField = treeOpts.children || treeOpts.childrenField;
6197
6533
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6198
6534
  const { checkField, checkStrictly, checkMethod } = checkboxOpts;
6199
- const { afterTreeFullData } = internalData;
6200
6535
  if (checkStrictly) {
6201
6536
  return;
6202
6537
  }
6203
- // 树结构
6204
- if (treeConfig) {
6538
+ if (isRowGroupStatus || treeConfig) {
6205
6539
  const { handleGetRowId } = createHandleGetRowId($xeTable);
6206
6540
  const childRowMaps = {};
6207
6541
  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]);
6542
+ if (isRowGroupStatus) {
6543
+ // 行分组
6544
+ const mapChildrenField = rowGroupOpts.mapChildrenField;
6545
+ if (mapChildrenField) {
6546
+ XEUtils.eachTree(afterGroupFullData, (row) => {
6547
+ const rowid = handleGetRowId(row);
6548
+ const childList = row[mapChildrenField];
6549
+ if (childList && childList.length && !childRowMaps[rowid]) {
6550
+ childRowMaps[rowid] = 1;
6551
+ childRowList.unshift([row, rowid, childList]);
6552
+ }
6553
+ }, { children: mapChildrenField });
6214
6554
  }
6215
- }, { children: transform ? mapChildrenField : childrenField });
6555
+ }
6556
+ else if (treeConfig) {
6557
+ // 树结构
6558
+ const { transform, mapChildrenField } = treeOpts;
6559
+ XEUtils.eachTree(afterTreeFullData, (row) => {
6560
+ const rowid = handleGetRowId(row);
6561
+ const childList = row[transform ? mapChildrenField : childrenField];
6562
+ if (childList && childList.length && !childRowMaps[rowid]) {
6563
+ childRowMaps[rowid] = 1;
6564
+ childRowList.unshift([row, rowid, childList]);
6565
+ }
6566
+ }, { children: transform ? mapChildrenField : childrenField });
6567
+ }
6216
6568
  childRowList.forEach(vals => {
6217
6569
  const row = vals[0];
6218
6570
  const rowid = vals[1];
@@ -6224,7 +6576,7 @@ const Methods = {
6224
6576
  ? (item) => {
6225
6577
  const childRowid = handleGetRowId(item);
6226
6578
  const isSelect = checkField ? XEUtils.get(item, checkField) : selectCheckboxMaps[childRowid];
6227
- if (checkMethod({ row: item })) {
6579
+ if (checkMethod({ $table: $xeTable, row: item })) {
6228
6580
  if (isSelect) {
6229
6581
  sLen++;
6230
6582
  }
@@ -6291,19 +6643,20 @@ const Methods = {
6291
6643
  const reactData = $xeTable;
6292
6644
  const internalData = $xeTable;
6293
6645
  const { treeConfig } = props;
6294
- const { afterFullData, afterTreeFullData, checkboxReserveRowMap, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6646
+ const { isRowGroupStatus } = reactData;
6647
+ const { afterFullData, afterTreeFullData, afterGroupFullData, checkboxReserveRowMap, selectCheckboxMaps, treeIndeterminateRowMaps } = internalData;
6295
6648
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6296
6649
  const { checkField, checkMethod, showReserveStatus } = checkboxOpts;
6297
6650
  const { handleGetRowId } = createHandleGetRowId($xeTable);
6298
6651
  let sLen = 0; // 已选
6299
6652
  let hLen = 0; // 半选
6300
6653
  let vLen = 0; // 有效行
6301
- const rootList = (treeConfig ? afterTreeFullData : afterFullData);
6654
+ const rootList = (treeConfig ? afterTreeFullData : (isRowGroupStatus ? afterGroupFullData : afterFullData));
6302
6655
  rootList.forEach(checkMethod
6303
6656
  ? row => {
6304
6657
  const childRowid = handleGetRowId(row);
6305
6658
  const selected = checkField ? XEUtils.get(row, checkField) : selectCheckboxMaps[childRowid];
6306
- if (checkMethod({ row })) {
6659
+ if (checkMethod({ $table: $xeTable, row })) {
6307
6660
  if (selected) {
6308
6661
  sLen++;
6309
6662
  }
@@ -6793,20 +7146,22 @@ const Methods = {
6793
7146
  const radioOpts = $xeTable.computeRadioOpts;
6794
7147
  const checkboxOpts = $xeTable.computeCheckboxOpts;
6795
7148
  const keyboardOpts = $xeTable.computeKeyboardOpts;
7149
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
6796
7150
  const rowOpts = $xeTable.computeRowOpts;
6797
7151
  const columnOpts = $xeTable.computeColumnOpts;
6798
7152
  const currentColumnOpts = $xeTable.computeCurrentColumnOpts;
6799
7153
  const { actived, focused } = editStore;
6800
7154
  const { row, column } = params;
6801
- const { type, treeNode } = column;
7155
+ const { type, treeNode, rowGroupNode } = column;
6802
7156
  const isRadioType = type === 'radio';
6803
7157
  const isCheckboxType = type === 'checkbox';
6804
7158
  const isExpandType = type === 'expand';
6805
7159
  const cell = evnt.currentTarget;
6806
7160
  const triggerRadio = isRadioType && getEventTargetNode(evnt, cell, 'vxe-cell--radio').flag;
6807
7161
  const triggerCheckbox = isCheckboxType && getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
6808
- const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-tree--btn-wrapper').flag;
7162
+ const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-cell--tree-btn').flag;
6809
7163
  const triggerExpandNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-table--expanded').flag;
7164
+ const triggerRowGroupNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-row-group--node-btn').flag;
6810
7165
  params = Object.assign({ cell, triggerRadio, triggerCheckbox, triggerTreeNode, triggerExpandNode }, params);
6811
7166
  if (!triggerCheckbox && !triggerRadio) {
6812
7167
  // 如果是展开行
@@ -6817,11 +7172,15 @@ const Methods = {
6817
7172
  if ((treeOpts.trigger === 'row' || (treeNode && treeOpts.trigger === 'cell'))) {
6818
7173
  $xeTable.triggerTreeExpandEvent(evnt, params);
6819
7174
  }
7175
+ // 如果是行分组
7176
+ if ((rowGroupOpts.trigger === 'row' || (rowGroupNode && rowGroupOpts.trigger === 'cell'))) {
7177
+ $xeTable.triggerRowGroupExpandEvent(evnt, params);
7178
+ }
6820
7179
  }
6821
7180
  // 如果点击了树节点
6822
7181
  if (!triggerTreeNode) {
6823
- if (!triggerExpandNode) {
6824
- // 如果是高亮行
7182
+ if (!triggerExpandNode && !triggerRowGroupNode) {
7183
+ // 如果是当前行
6825
7184
  if (rowOpts.isCurrent || highlightCurrentRow) {
6826
7185
  if (!triggerCheckbox && !triggerRadio) {
6827
7186
  $xeTable.triggerCurrentRowEvent(evnt, params);
@@ -7033,7 +7392,7 @@ const Methods = {
7033
7392
  const triggerInput = cell && cell.tagName && cell.tagName.toLowerCase() === 'input';
7034
7393
  const triggerRadio = isRadioType && getEventTargetNode(evnt, cell, 'vxe-cell--radio').flag;
7035
7394
  const triggerCheckbox = isCheckboxType && getEventTargetNode(evnt, cell, 'vxe-cell--checkbox').flag;
7036
- const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-tree--btn-wrapper').flag;
7395
+ const triggerTreeNode = treeNode && getEventTargetNode(evnt, cell, 'vxe-cell--tree-btn').flag;
7037
7396
  const triggerExpandNode = isExpandType && getEventTargetNode(evnt, cell, 'vxe-table--expanded').flag;
7038
7397
  let isColDragCell = false;
7039
7398
  if (rowOpts.drag) {
@@ -7307,7 +7666,7 @@ const Methods = {
7307
7666
  evnt.preventDefault();
7308
7667
  return;
7309
7668
  }
7310
- const hasCtrlKey = evnt.ctrlKey;
7669
+ const isControlKey = hasControlKey(evnt);
7311
7670
  const trEl = evnt.currentTarget;
7312
7671
  const rowid = trEl.getAttribute('rowid') || '';
7313
7672
  const rest = fullAllDataRowIdData[rowid];
@@ -7319,11 +7678,11 @@ const Methods = {
7319
7678
  const { dragRow } = reactData;
7320
7679
  const offsetY = evnt.clientY - trEl.getBoundingClientRect().y;
7321
7680
  const dragPos = offsetY < trEl.clientHeight / 2 ? 'top' : 'bottom';
7322
- internalData.prevDragToChild = !!(treeConfig && transform && isToChildDrag && hasCtrlKey);
7681
+ internalData.prevDragToChild = !!(treeConfig && transform && isToChildDrag && isControlKey);
7323
7682
  internalData.prevDragRow = row;
7324
7683
  internalData.prevDragPos = dragPos;
7325
7684
  if ($xeTable.eqRow(dragRow, row) ||
7326
- (hasCtrlKey && treeConfig && lazy && row[hasChildField] && rowRest && !rowRest.treeLoaded) ||
7685
+ (isControlKey && treeConfig && lazy && row[hasChildField] && rowRest && !rowRest.treeLoaded) ||
7327
7686
  (!isCrossDrag && treeConfig && transform && (isPeerDrag ? dragRow[parentField] !== row[parentField] : rest.level))) {
7328
7687
  showDropTip($xeTable, evnt, trEl, null, false, dragPos);
7329
7688
  return;
@@ -7588,7 +7947,7 @@ const Methods = {
7588
7947
  evnt.preventDefault();
7589
7948
  return;
7590
7949
  }
7591
- const hasCtrlKey = evnt.ctrlKey;
7950
+ const isControlKey = hasControlKey(evnt);
7592
7951
  const thEl = evnt.currentTarget;
7593
7952
  const colid = thEl.getAttribute('colid');
7594
7953
  const column = $xeTable.getColumnById(colid);
@@ -7597,7 +7956,7 @@ const Methods = {
7597
7956
  const { clientX } = evnt;
7598
7957
  const offsetX = clientX - thEl.getBoundingClientRect().x;
7599
7958
  const dragPos = offsetX < thEl.clientWidth / 2 ? 'left' : 'right';
7600
- internalData.prevDragToChild = !!((isCrossDrag && isToChildDrag) && hasCtrlKey);
7959
+ internalData.prevDragToChild = !!((isCrossDrag && isToChildDrag) && isControlKey);
7601
7960
  internalData.prevDragCol = column;
7602
7961
  internalData.prevDragPos = dragPos;
7603
7962
  if (column.fixed ||
@@ -8001,7 +8360,7 @@ const Methods = {
8001
8360
  const $xeTable = this;
8002
8361
  const reactData = $xeTable;
8003
8362
  const internalData = $xeTable;
8004
- const { expandColumn: column } = reactData;
8363
+ const { expandColumn } = reactData;
8005
8364
  const { rowExpandLazyLoadedMaps } = internalData;
8006
8365
  const expandOpts = $xeTable.computeExpandOpts;
8007
8366
  const { row } = params;
@@ -8013,12 +8372,12 @@ const Methods = {
8013
8372
  const rowid = getRowid($xeTable, row);
8014
8373
  if (!lazy || !rowExpandLazyLoadedMaps[rowid]) {
8015
8374
  const expanded = !$xeTable.isRowExpandByRow(row);
8016
- const columnIndex = $xeTable.getColumnIndex(column);
8017
- const $columnIndex = $xeTable.getVMColumnIndex(column);
8375
+ const columnIndex = expandColumn ? $xeTable.getColumnIndex(expandColumn) : -1;
8376
+ const $columnIndex = expandColumn ? $xeTable.getVMColumnIndex(expandColumn) : -1;
8018
8377
  $xeTable.setRowExpand(row, expanded);
8019
8378
  $xeTable.dispatchEvent('toggle-row-expand', {
8020
8379
  expanded,
8021
- column,
8380
+ column: expandColumn,
8022
8381
  columnIndex,
8023
8382
  $columnIndex,
8024
8383
  row,
@@ -8068,8 +8427,8 @@ const Methods = {
8068
8427
  const expandOpts = $xeTable.computeExpandOpts;
8069
8428
  const { reserve, lazy, accordion, toggleMethod } = expandOpts;
8070
8429
  const lazyRests = [];
8071
- const columnIndex = $xeTable.getColumnIndex(expandColumn);
8072
- const $columnIndex = $xeTable.getVMColumnIndex(expandColumn);
8430
+ const columnIndex = expandColumn ? $xeTable.getColumnIndex(expandColumn) : -1;
8431
+ const $columnIndex = expandColumn ? $xeTable.getVMColumnIndex(expandColumn) : -1;
8073
8432
  if (rows) {
8074
8433
  if (!XEUtils.isArray(rows)) {
8075
8434
  rows = [rows];
@@ -8181,6 +8540,88 @@ const Methods = {
8181
8540
  });
8182
8541
  return rest;
8183
8542
  },
8543
+ setRowGroups(fieldOrColumns) {
8544
+ const $xeTable = this;
8545
+ const props = $xeTable;
8546
+ const internalData = $xeTable;
8547
+ const { rowGroupConfig } = props;
8548
+ if (!rowGroupConfig) {
8549
+ errLog('vxe.error.reqProp', ['row-group-config']);
8550
+ return $xeTable.$nextTick();
8551
+ }
8552
+ if (fieldOrColumns) {
8553
+ handleUpdateRowGroup($xeTable, (XEUtils.isArray(fieldOrColumns) ? fieldOrColumns : [fieldOrColumns]).map(fieldOrColumn => {
8554
+ return XEUtils.isString(fieldOrColumn) ? fieldOrColumn : fieldOrColumn.field;
8555
+ }));
8556
+ return loadTableData($xeTable, internalData.tableSynchData, true);
8557
+ }
8558
+ return $xeTable.$nextTick();
8559
+ },
8560
+ clearRowGroups() {
8561
+ const $xeTable = this;
8562
+ const props = $xeTable;
8563
+ const internalData = $xeTable;
8564
+ const { rowGroupConfig } = props;
8565
+ if (!rowGroupConfig) {
8566
+ errLog('vxe.error.reqProp', ['row-group-config']);
8567
+ return $xeTable.$nextTick();
8568
+ }
8569
+ handleUpdateRowGroup($xeTable, []);
8570
+ return loadTableData($xeTable, internalData.tableSynchData, true);
8571
+ },
8572
+ isRowGroupRecord(row) {
8573
+ const $xeTable = this;
8574
+ const reactData = $xeTable;
8575
+ const { isRowGroupStatus } = reactData;
8576
+ return isRowGroupStatus && row.isAggregate;
8577
+ },
8578
+ isRowGroupExpandByRow(row) {
8579
+ const $xeTable = this;
8580
+ const reactData = $xeTable;
8581
+ const internalData = $xeTable;
8582
+ const { rowGroupExpandedFlag } = reactData;
8583
+ const { rowGroupExpandedMaps } = internalData;
8584
+ return !!rowGroupExpandedFlag && !!rowGroupExpandedMaps[getRowid($xeTable, row)];
8585
+ },
8586
+ setRowGroupExpand(rows, expanded) {
8587
+ const $xeTable = this;
8588
+ if (rows) {
8589
+ if (!XEUtils.isArray(rows)) {
8590
+ rows = [rows];
8591
+ }
8592
+ return handleRowGroupVirtualExpand($xeTable, rows, expanded);
8593
+ }
8594
+ return $xeTable.$nextTick();
8595
+ },
8596
+ setAllRowGroupExpand(expanded) {
8597
+ const $xeTable = this;
8598
+ const reactData = $xeTable;
8599
+ const internalData = $xeTable;
8600
+ const { tableFullGroupData } = internalData;
8601
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
8602
+ const { mapChildrenField } = rowGroupOpts;
8603
+ const rgExpandedMaps = {};
8604
+ if (expanded && mapChildrenField) {
8605
+ XEUtils.eachTree(tableFullGroupData, (row) => {
8606
+ if (row[mapChildrenField] && row[mapChildrenField].length) {
8607
+ rgExpandedMaps[getRowid($xeTable, row)] = row;
8608
+ }
8609
+ }, { children: mapChildrenField });
8610
+ }
8611
+ internalData.rowGroupExpandedMaps = rgExpandedMaps;
8612
+ handleVirtualTreeToList($xeTable);
8613
+ reactData.rowGroupExpandedFlag++;
8614
+ return $xeTable.handleTableData();
8615
+ },
8616
+ clearRowGroupExpand() {
8617
+ const $xeTable = this;
8618
+ const reactData = $xeTable;
8619
+ const internalData = $xeTable;
8620
+ internalData.rowGroupExpandedMaps = {};
8621
+ handleVirtualTreeToList($xeTable);
8622
+ reactData.rowGroupExpandedFlag++;
8623
+ return $xeTable.handleTableData();
8624
+ },
8184
8625
  getTreeExpandRecords() {
8185
8626
  const $xeTable = this;
8186
8627
  const internalData = $xeTable;
@@ -8242,11 +8683,11 @@ const Methods = {
8242
8683
  });
8243
8684
  }
8244
8685
  internalData.treeExpandedMaps = {};
8245
- reactData.treeExpandedFlag++;
8246
8686
  if (transform) {
8247
8687
  handleVirtualTreeToList($xeTable);
8248
- return $xeTable.handleTableData();
8688
+ $xeTable.handleTableData();
8249
8689
  }
8690
+ reactData.treeExpandedFlag++;
8250
8691
  return $xeTable.$nextTick();
8251
8692
  },
8252
8693
  /**
@@ -8255,6 +8696,7 @@ const Methods = {
8255
8696
  */
8256
8697
  reloadTreeExpand(row) {
8257
8698
  const $xeTable = this;
8699
+ const reactData = $xeTable;
8258
8700
  const internalData = $xeTable;
8259
8701
  const { treeExpandLazyLoadedMaps } = internalData;
8260
8702
  const treeOpts = $xeTable.computeTreeOpts;
@@ -8267,8 +8709,9 @@ const Methods = {
8267
8709
  }).then(() => {
8268
8710
  if (transform) {
8269
8711
  handleVirtualTreeToList($xeTable);
8270
- return $xeTable.handleTableData();
8712
+ $xeTable.handleTableData();
8271
8713
  }
8714
+ reactData.treeExpandedFlag++;
8272
8715
  }).then(() => {
8273
8716
  return $xeTable.recalculate();
8274
8717
  });
@@ -8283,6 +8726,27 @@ const Methods = {
8283
8726
  // 即将废弃
8284
8727
  return $xeTable.reloadTreeExpand(row);
8285
8728
  },
8729
+ /**
8730
+ * 行分组事件
8731
+ */
8732
+ triggerRowGroupExpandEvent(evnt, params) {
8733
+ const $xeTable = this;
8734
+ const internalData = $xeTable;
8735
+ const { rowGroupExpandedMaps } = internalData;
8736
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
8737
+ const { row, column } = params;
8738
+ const { trigger } = rowGroupOpts;
8739
+ if (trigger === 'manual') {
8740
+ return;
8741
+ }
8742
+ evnt.stopPropagation();
8743
+ const rowid = getRowid($xeTable, row);
8744
+ const expanded = !rowGroupExpandedMaps[rowid];
8745
+ const columnIndex = $xeTable.getColumnIndex(column);
8746
+ const $columnIndex = $xeTable.getVMColumnIndex(column);
8747
+ $xeTable.setRowGroupExpand(row, expanded);
8748
+ $xeTable.dispatchEvent('toggle-row-group-expand', { expanded, column, columnIndex, $columnIndex, row }, evnt);
8749
+ },
8286
8750
  /**
8287
8751
  * 展开树节点事件
8288
8752
  */
@@ -8327,8 +8791,12 @@ const Methods = {
8327
8791
  * @param {Boolean} expanded 是否展开
8328
8792
  */
8329
8793
  setAllTreeExpand(expanded) {
8330
- const { tableFullData, treeOpts } = this;
8331
- const { lazy } = treeOpts;
8794
+ const $xeTable = this;
8795
+ const reactData = $xeTable;
8796
+ const internalData = $xeTable;
8797
+ const { tableFullData } = internalData;
8798
+ const treeOpts = $xeTable.computeTreeOpts;
8799
+ const { transform, lazy } = treeOpts;
8332
8800
  const childrenField = treeOpts.children || treeOpts.childrenField;
8333
8801
  const expandeds = [];
8334
8802
  XEUtils.eachTree(tableFullData, (row) => {
@@ -8337,7 +8805,13 @@ const Methods = {
8337
8805
  expandeds.push(row);
8338
8806
  }
8339
8807
  }, { children: childrenField });
8340
- return this.setTreeExpand(expandeds, expanded);
8808
+ return $xeTable.setTreeExpand(expandeds, expanded).then(() => {
8809
+ if (transform) {
8810
+ handleVirtualTreeToList($xeTable);
8811
+ reactData.treeExpandedFlag++;
8812
+ return $xeTable.recalculate();
8813
+ }
8814
+ });
8341
8815
  },
8342
8816
  /**
8343
8817
  * 设置展开树形节点,二个参数设置这一行展开与否
@@ -8391,15 +8865,15 @@ const Methods = {
8391
8865
  const { transform, reserve } = treeOpts;
8392
8866
  const expList = $xeTable.getTreeExpandRecords();
8393
8867
  internalData.treeExpandedMaps = {};
8394
- reactData.treeExpandedFlag++;
8395
8868
  if (reserve) {
8396
8869
  XEUtils.eachTree(tableFullTreeData, row => handleTreeExpandReserve($xeTable, row, false), { children: childrenField });
8397
8870
  }
8398
8871
  return $xeTable.handleTableData().then(() => {
8399
8872
  if (transform) {
8400
8873
  handleVirtualTreeToList($xeTable);
8401
- return $xeTable.handleTableData();
8874
+ $xeTable.handleTableData();
8402
8875
  }
8876
+ reactData.treeExpandedFlag++;
8403
8877
  }).then(() => {
8404
8878
  if (expList.length) {
8405
8879
  $xeTable.recalculate();
@@ -9184,21 +9658,29 @@ const Methods = {
9184
9658
  * @param {Row} row 行对象
9185
9659
  */
9186
9660
  scrollToTreeRow(row) {
9187
- const { tableFullData, treeConfig, treeOpts } = this;
9188
- const childrenField = treeOpts.children || treeOpts.childrenField;
9661
+ const $xeTable = this;
9662
+ const props = $xeTable;
9663
+ const reactData = $xeTable;
9664
+ const internalData = $xeTable;
9665
+ const { treeConfig } = props;
9666
+ const { isRowGroupStatus } = reactData;
9667
+ const { tableFullData } = internalData;
9189
9668
  const rests = [];
9190
- if (treeConfig) {
9191
- const matchObj = XEUtils.findTree(tableFullData, item => item === row, { children: childrenField });
9669
+ if (treeConfig || isRowGroupStatus) {
9670
+ const rowGroupOpts = $xeTable.computeRowGroupOpts;
9671
+ const treeOpts = $xeTable.computeTreeOpts;
9672
+ const childrenField = treeOpts.children || treeOpts.childrenField;
9673
+ const matchObj = XEUtils.findTree(tableFullData, item => $xeTable.eqRow(item, row), { children: isRowGroupStatus ? rowGroupOpts.mapChildrenField : childrenField });
9192
9674
  if (matchObj) {
9193
9675
  const nodes = matchObj.nodes;
9194
9676
  nodes.forEach((row, index) => {
9195
- if (index < nodes.length - 1 && !this.isTreeExpandByRow(row)) {
9196
- rests.push(this.setTreeExpand(row, true));
9677
+ if (index < nodes.length - 1 && !$xeTable.isTreeExpandByRow(row)) {
9678
+ rests.push($xeTable.setTreeExpand(row, true));
9197
9679
  }
9198
9680
  });
9199
9681
  }
9200
9682
  }
9201
- return Promise.all(rests).then(() => rowToVisible(this, row));
9683
+ return Promise.all(rests).then(() => rowToVisible($xeTable, row));
9202
9684
  },
9203
9685
  /**
9204
9686
  * 手动清除滚动相关信息,还原到初始状态