vxe-table 3.13.17 → 3.14.0-beta.1

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 (33) hide show
  1. package/es/grid/src/grid.js +41 -31
  2. package/es/style.css +1 -1
  3. package/es/table/module/keyboard/mixin.js +2 -2
  4. package/es/table/src/methods.js +282 -163
  5. package/es/table/src/table.js +52 -51
  6. package/es/ui/index.js +1 -1
  7. package/es/ui/src/log.js +1 -1
  8. package/lib/grid/src/grid.js +41 -32
  9. package/lib/grid/src/grid.min.js +1 -1
  10. package/lib/index.umd.js +1604 -2547
  11. package/lib/index.umd.min.js +1 -1
  12. package/lib/style.css +1 -1
  13. package/lib/table/module/keyboard/mixin.js +2 -2
  14. package/lib/table/module/keyboard/mixin.min.js +1 -1
  15. package/lib/table/src/methods.js +298 -169
  16. package/lib/table/src/methods.min.js +1 -1
  17. package/lib/table/src/table.js +52 -51
  18. package/lib/table/src/table.min.js +1 -1
  19. package/lib/ui/index.js +1 -1
  20. package/lib/ui/index.min.js +1 -1
  21. package/lib/ui/src/log.js +1 -1
  22. package/lib/ui/src/log.min.js +1 -1
  23. package/package.json +1 -1
  24. package/packages/grid/src/grid.ts +41 -31
  25. package/packages/table/module/keyboard/mixin.ts +2 -2
  26. package/packages/table/src/methods.ts +300 -173
  27. package/packages/table/src/table.ts +55 -53
  28. /package/es/{iconfont.1741051533862.ttf → iconfont.1741051885975.ttf} +0 -0
  29. /package/es/{iconfont.1741051533862.woff → iconfont.1741051885975.woff} +0 -0
  30. /package/es/{iconfont.1741051533862.woff2 → iconfont.1741051885975.woff2} +0 -0
  31. /package/lib/{iconfont.1741051533862.ttf → iconfont.1741051885975.ttf} +0 -0
  32. /package/lib/{iconfont.1741051533862.woff → iconfont.1741051885975.woff} +0 -0
  33. /package/lib/{iconfont.1741051533862.woff2 → iconfont.1741051885975.woff2} +0 -0
@@ -8,6 +8,8 @@ import { getSlotVNs } from '../../ui/src/vn';
8
8
  import { warnLog, errLog } from '../../ui/src/log';
9
9
  const { getConfig, getI18n, renderer, formats, interceptor, createEvent } = VxeUI;
10
10
  const customStorageKey = 'VXE_CUSTOM_STORE';
11
+ const maxYHeight = 5e6;
12
+ const maxXWidth = 5e6;
11
13
  function eqCellValue(row1, row2, field) {
12
14
  const val1 = XEUtils.get(row1, field);
13
15
  const val2 = XEUtils.get(row2, field);
@@ -61,28 +63,44 @@ function handleReserveRow($xeTable, reserveRowMap) {
61
63
  return reserveList;
62
64
  }
63
65
  function handleVirtualXVisible($xeTable) {
66
+ const reactData = $xeTable;
64
67
  const internalData = $xeTable;
65
- const { elemStore, visibleColumn } = internalData;
68
+ const { isScrollXBig, scrollXWidth } = reactData;
69
+ const { elemStore, visibleColumn, fullColumnIdData } = internalData;
66
70
  const leftFixedWidth = $xeTable.computeLeftFixedWidth;
67
71
  const rightFixedWidth = $xeTable.computeRightFixedWidth;
68
72
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
69
73
  if (bodyScrollElem) {
70
- const { scrollLeft, clientWidth } = bodyScrollElem;
71
- const startWidth = scrollLeft + leftFixedWidth;
72
- const endWidth = scrollLeft + clientWidth - rightFixedWidth;
73
- let toVisibleIndex = -1;
74
- let cWidth = 0;
75
- let visibleSize = 0;
76
- for (let colIndex = 0, colLen = visibleColumn.length; colIndex < colLen; colIndex++) {
77
- cWidth += visibleColumn[colIndex].renderWidth;
78
- if (toVisibleIndex === -1 && startWidth < cWidth) {
79
- toVisibleIndex = colIndex;
74
+ const clientWidth = bodyScrollElem.clientWidth;
75
+ let scrollLeft = bodyScrollElem.scrollLeft;
76
+ if (isScrollXBig) {
77
+ scrollLeft = Math.ceil((scrollXWidth - clientWidth) * Math.min(1, (scrollLeft / (maxXWidth - clientWidth))));
78
+ }
79
+ const startLeft = scrollLeft + leftFixedWidth;
80
+ const endLeft = scrollLeft + clientWidth - rightFixedWidth;
81
+ let leftIndex = 0;
82
+ let rightIndex = visibleColumn.length;
83
+ while (leftIndex < rightIndex) {
84
+ const cIndex = Math.floor((leftIndex + rightIndex) / 2);
85
+ const column = visibleColumn[cIndex];
86
+ const colid = column.id;
87
+ const colRest = fullColumnIdData[colid] || {};
88
+ if (colRest.oLeft <= startLeft) {
89
+ leftIndex = cIndex + 1;
80
90
  }
81
- if (toVisibleIndex >= 0) {
82
- visibleSize++;
83
- if (cWidth > endWidth) {
84
- break;
85
- }
91
+ else {
92
+ rightIndex = cIndex;
93
+ }
94
+ }
95
+ let visibleSize = 0;
96
+ const toVisibleIndex = Math.max(0, leftIndex < visibleColumn.length ? leftIndex - 2 : 0);
97
+ for (let cIndex = toVisibleIndex, cLen = visibleColumn.length; cIndex < cLen; cIndex++) {
98
+ const column = visibleColumn[cIndex];
99
+ const colid = column.id;
100
+ const colRest = fullColumnIdData[colid] || {};
101
+ visibleSize++;
102
+ if (colRest.oLeft > endLeft || visibleSize >= 60) {
103
+ break;
86
104
  }
87
105
  }
88
106
  return { toVisibleIndex: Math.max(0, toVisibleIndex), visibleSize: Math.max(1, visibleSize) };
@@ -396,8 +414,8 @@ function updateStyle($xeTable) {
396
414
  const reactData = $xeTable;
397
415
  const internalData = $xeTable;
398
416
  const { border, showHeaderOverflow: allColumnHeaderOverflow, showFooterOverflow: allColumnFooterOverflow, mouseConfig, spanMethod, footerSpanMethod } = props;
399
- const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, overflowX, scrollbarWidth, overflowY, scrollbarHeight, columnStore, editStore, isAllOverflow, expandColumn } = reactData;
400
- const { visibleColumn, fullColumnIdData, tableHeight, tableWidth, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData;
417
+ const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, overflowX, scrollbarWidth, overflowY, scrollbarHeight, scrollXWidth, columnStore, editStore, isAllOverflow, expandColumn } = reactData;
418
+ const { visibleColumn, fullColumnIdData, tableHeight, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData;
401
419
  const el = $xeTable.$refs.refElem;
402
420
  if (!el) {
403
421
  return;
@@ -435,9 +453,9 @@ function updateStyle($xeTable) {
435
453
  }
436
454
  bodyHeight = Math.max(bodyMinHeight, bodyHeight);
437
455
  }
456
+ const scrollbarXToTop = $xeTable.$refs.computeScrollbarXToTop;
438
457
  const xLeftCornerEl = $xeTable.$refs.refScrollXLeftCornerElem;
439
458
  const xRightCornerEl = $xeTable.$refs.refScrollXRightCornerElem;
440
- const scrollbarXToTop = $xeTable.computeScrollbarXToTop;
441
459
  const scrollXVirtualEl = $xeTable.$refs.refScrollXVirtualElem;
442
460
  if (scrollXVirtualEl) {
443
461
  scrollXVirtualEl.style.height = `${osbHeight}px`;
@@ -527,7 +545,7 @@ function updateStyle($xeTable) {
527
545
  if (fixedType) {
528
546
  if (isGroup) {
529
547
  if (wrapperElem) {
530
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : '';
548
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
531
549
  }
532
550
  }
533
551
  else {
@@ -538,7 +556,7 @@ function updateStyle($xeTable) {
538
556
  }
539
557
  else {
540
558
  if (wrapperElem) {
541
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : '';
559
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
542
560
  }
543
561
  }
544
562
  }
@@ -549,10 +567,6 @@ function updateStyle($xeTable) {
549
567
  if (tableElem) {
550
568
  tableElem.style.width = tWidth ? `${tWidth}px` : '';
551
569
  }
552
- const repairElem = getRefElem(elemStore[`${name}-${layout}-repair`]);
553
- if (repairElem) {
554
- repairElem.style.width = `${tableWidth}px`;
555
- }
556
570
  const listElem = getRefElem(elemStore[`${name}-${layout}-list`]);
557
571
  if (isGroup && listElem) {
558
572
  XEUtils.arrayEach(listElem.querySelectorAll('.col--group'), (thElem) => {
@@ -620,7 +634,7 @@ function updateStyle($xeTable) {
620
634
  }
621
635
  else {
622
636
  if (wrapperElem) {
623
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : '';
637
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
624
638
  }
625
639
  }
626
640
  }
@@ -661,7 +675,7 @@ function updateStyle($xeTable) {
661
675
  }
662
676
  else {
663
677
  if (wrapperElem) {
664
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : '';
678
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : '';
665
679
  }
666
680
  }
667
681
  }
@@ -984,46 +998,53 @@ function computeRowHeight($xeTable) {
984
998
  // 最低支持 18px 行高
985
999
  return Math.max(18, rowHeight);
986
1000
  }
987
- function handleVirtualYVisible($xeTable, currScrollTop) {
1001
+ function handleVirtualYVisible($xeTable) {
988
1002
  const reactData = $xeTable;
989
1003
  const internalData = $xeTable;
990
- const { isAllOverflow, expandColumn, rowExpandedMaps } = reactData;
1004
+ const { isAllOverflow, expandColumn, isScrollYBig, scrollYHeight } = reactData;
991
1005
  const { elemStore, isResizeCellHeight, afterFullData, fullAllDataRowIdData } = internalData;
992
- const expandOpts = $xeTable.computeExpandOpts;
993
1006
  const rowOpts = $xeTable.computeRowOpts;
994
1007
  const cellOpts = $xeTable.computeCellOpts;
995
1008
  const defaultRowHeight = $xeTable.computeDefaultRowHeight;
996
1009
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
997
1010
  if (bodyScrollElem) {
998
1011
  const clientHeight = bodyScrollElem.clientHeight;
999
- const scrollTop = XEUtils.isNumber(currScrollTop) ? currScrollTop : bodyScrollElem.scrollTop;
1000
- const endHeight = scrollTop + clientHeight;
1012
+ let scrollTop = bodyScrollElem.scrollTop;
1013
+ if (isScrollYBig) {
1014
+ scrollTop = Math.ceil((scrollYHeight - clientHeight) * Math.min(1, (scrollTop / (maxYHeight - clientHeight))));
1015
+ }
1016
+ const startTop = scrollTop;
1017
+ const endTop = scrollTop + clientHeight;
1001
1018
  let toVisibleIndex = -1;
1002
- let offsetTop = 0;
1003
1019
  let visibleSize = 0;
1004
1020
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height;
1005
1021
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
1006
- toVisibleIndex = Math.floor(scrollTop / defaultRowHeight);
1022
+ toVisibleIndex = Math.floor(startTop / defaultRowHeight) - 1;
1007
1023
  visibleSize = Math.ceil(clientHeight / defaultRowHeight) + 1;
1008
1024
  }
1009
1025
  else {
1010
- for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
1026
+ let leftIndex = 0;
1027
+ let rightIndex = afterFullData.length;
1028
+ while (leftIndex < rightIndex) {
1029
+ const rIndex = Math.floor((leftIndex + rightIndex) / 2);
1011
1030
  const row = afterFullData[rIndex];
1012
1031
  const rowid = getRowid($xeTable, row);
1013
1032
  const rowRest = fullAllDataRowIdData[rowid] || {};
1014
- offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
1015
- if (toVisibleIndex === -1 && scrollTop < offsetTop) {
1016
- toVisibleIndex = rIndex;
1033
+ if (rowRest.oTop <= startTop) {
1034
+ leftIndex = rIndex + 1;
1017
1035
  }
1018
- if (toVisibleIndex >= 0) {
1019
- visibleSize++;
1020
- if (offsetTop > endHeight) {
1021
- break;
1022
- }
1036
+ else {
1037
+ rightIndex = rIndex;
1023
1038
  }
1024
- // 是否展开行
1025
- if (expandColumn && rowExpandedMaps[rowid]) {
1026
- offsetTop += rowRest.expandHeight || expandOpts.height || 0;
1039
+ }
1040
+ toVisibleIndex = Math.max(0, leftIndex < afterFullData.length ? leftIndex - 2 : 0);
1041
+ for (let rIndex = toVisibleIndex, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
1042
+ const row = afterFullData[rIndex];
1043
+ const rowid = getRowid($xeTable, row);
1044
+ const rowRest = fullAllDataRowIdData[rowid] || {};
1045
+ visibleSize++;
1046
+ if (rowRest.oTop > endTop || visibleSize >= 100) {
1047
+ break;
1027
1048
  }
1028
1049
  }
1029
1050
  }
@@ -1178,7 +1199,7 @@ function autoCellWidth($xeTable) {
1178
1199
  if (!xHandleEl) {
1179
1200
  return;
1180
1201
  }
1181
- let tableWidth = 0;
1202
+ let tWidth = 0;
1182
1203
  const minCellWidth = 40; // 列宽最少限制 40px
1183
1204
  const bodyWidth = bodyElem.clientWidth;
1184
1205
  let remainWidth = bodyWidth;
@@ -1189,51 +1210,51 @@ function autoCellWidth($xeTable) {
1189
1210
  // 最小宽
1190
1211
  pxMinList.forEach((column) => {
1191
1212
  const minWidth = XEUtils.toInteger(column.minWidth);
1192
- tableWidth += minWidth;
1213
+ tWidth += minWidth;
1193
1214
  column.renderWidth = minWidth;
1194
1215
  });
1195
1216
  // 最小自适应
1196
1217
  autoMinList.forEach((column) => {
1197
1218
  const scaleWidth = Math.max(60, XEUtils.toInteger(column.renderAutoWidth));
1198
- tableWidth += scaleWidth;
1219
+ tWidth += scaleWidth;
1199
1220
  column.renderWidth = scaleWidth;
1200
1221
  });
1201
1222
  // 最小百分比
1202
1223
  scaleMinList.forEach((column) => {
1203
1224
  const scaleWidth = Math.floor(XEUtils.toInteger(column.minWidth) * meanWidth);
1204
- tableWidth += scaleWidth;
1225
+ tWidth += scaleWidth;
1205
1226
  column.renderWidth = scaleWidth;
1206
1227
  });
1207
1228
  // 固定百分比
1208
1229
  scaleList.forEach((column) => {
1209
1230
  const scaleWidth = Math.floor(XEUtils.toInteger(column.width) * meanWidth);
1210
- tableWidth += scaleWidth;
1231
+ tWidth += scaleWidth;
1211
1232
  column.renderWidth = scaleWidth;
1212
1233
  });
1213
1234
  // 固定宽
1214
1235
  pxList.forEach((column) => {
1215
1236
  const width = XEUtils.toInteger(column.width);
1216
- tableWidth += width;
1237
+ tWidth += width;
1217
1238
  column.renderWidth = width;
1218
1239
  });
1219
1240
  // 自适应宽
1220
1241
  autoList.forEach((column) => {
1221
1242
  const width = Math.max(60, XEUtils.toInteger(column.renderAutoWidth));
1222
- tableWidth += width;
1243
+ tWidth += width;
1223
1244
  column.renderWidth = width;
1224
1245
  });
1225
1246
  // 调整了列宽
1226
1247
  resizeList.forEach((column) => {
1227
1248
  const width = XEUtils.toInteger(column.resizeWidth);
1228
- tableWidth += width;
1249
+ tWidth += width;
1229
1250
  column.renderWidth = width;
1230
1251
  });
1231
- remainWidth -= tableWidth;
1252
+ remainWidth -= tWidth;
1232
1253
  meanWidth = remainWidth > 0 ? Math.floor(remainWidth / (scaleMinList.length + pxMinList.length + autoMinList.length + remainList.length)) : 0;
1233
1254
  if (fit) {
1234
1255
  if (remainWidth > 0) {
1235
1256
  scaleMinList.concat(pxMinList).concat(autoMinList).forEach((column) => {
1236
- tableWidth += meanWidth;
1257
+ tWidth += meanWidth;
1237
1258
  column.renderWidth += meanWidth;
1238
1259
  });
1239
1260
  }
@@ -1245,7 +1266,7 @@ function autoCellWidth($xeTable) {
1245
1266
  remainList.forEach((column) => {
1246
1267
  const width = Math.max(meanWidth, minCellWidth);
1247
1268
  column.renderWidth = width;
1248
- tableWidth += width;
1269
+ tWidth += width;
1249
1270
  });
1250
1271
  if (fit) {
1251
1272
  /**
@@ -1255,13 +1276,13 @@ function autoCellWidth($xeTable) {
1255
1276
  const dynamicList = scaleList.concat(scaleMinList).concat(pxMinList).concat(autoMinList).concat(remainList);
1256
1277
  let dynamicSize = dynamicList.length - 1;
1257
1278
  if (dynamicSize > 0) {
1258
- let i = bodyWidth - tableWidth;
1279
+ let i = bodyWidth - tWidth;
1259
1280
  if (i > 0) {
1260
1281
  while (i > 0 && dynamicSize >= 0) {
1261
1282
  i--;
1262
1283
  dynamicList[dynamicSize--].renderWidth++;
1263
1284
  }
1264
- tableWidth = bodyWidth;
1285
+ tWidth = bodyWidth;
1265
1286
  }
1266
1287
  }
1267
1288
  }
@@ -1269,17 +1290,18 @@ function autoCellWidth($xeTable) {
1269
1290
  const overflowY = yHandleEl.scrollHeight > yHandleEl.clientHeight;
1270
1291
  reactData.scrollbarWidth = Math.max(scrollbarOpts.width || 0, yHandleEl.offsetWidth - yHandleEl.clientWidth);
1271
1292
  reactData.overflowY = overflowY;
1272
- internalData.tableWidth = tableWidth;
1293
+ reactData.scrollXWidth = tWidth;
1273
1294
  internalData.tableHeight = tableHeight;
1274
1295
  const headerTableElem = getRefElem(elemStore['main-header-table']);
1275
1296
  const footerTableElem = getRefElem(elemStore['main-footer-table']);
1276
1297
  const headerHeight = headerTableElem ? headerTableElem.clientHeight : 0;
1277
- const overflowX = tableWidth > bodyWidth;
1298
+ const overflowX = tWidth > bodyWidth;
1278
1299
  const footerHeight = footerTableElem ? footerTableElem.clientHeight : 0;
1279
1300
  reactData.scrollbarHeight = Math.max(scrollbarOpts.height || 0, xHandleEl.offsetHeight - xHandleEl.clientHeight);
1280
1301
  internalData.headerHeight = headerHeight;
1281
1302
  internalData.footerHeight = footerHeight;
1282
1303
  reactData.overflowX = overflowX;
1304
+ updateColumnOffsetLeft($xeTable);
1283
1305
  updateHeight($xeTable);
1284
1306
  reactData.parentHeight = Math.max(internalData.headerHeight + footerHeight + 20, $xeTable.getParentHeight());
1285
1307
  if (overflowX) {
@@ -1455,8 +1477,8 @@ function showDropTip($xeTable, evnt, trEl, thEl, showLine, dragPos) {
1455
1477
  const wrapperRect = el.getBoundingClientRect();
1456
1478
  const osbWidth = overflowY ? scrollbarWidth : 0;
1457
1479
  const osbHeight = overflowX ? scrollbarHeight : 0;
1458
- const tableWidth = el.clientWidth;
1459
- const tableHeight = el.clientHeight;
1480
+ const tableWrapperWidth = el.clientWidth;
1481
+ const tableWrapperHeight = el.clientHeight;
1460
1482
  if (trEl) {
1461
1483
  const rdLineEl = $xeTable.$refs.refDragRowLineElem;
1462
1484
  if (rdLineEl) {
@@ -1465,14 +1487,14 @@ function showDropTip($xeTable, evnt, trEl, thEl, showLine, dragPos) {
1465
1487
  const trRect = trEl.getBoundingClientRect();
1466
1488
  let trHeight = trEl.clientHeight;
1467
1489
  const offsetTop = Math.max(1, trRect.y - wrapperRect.y);
1468
- if (offsetTop + trHeight > tableHeight - osbHeight) {
1469
- trHeight = tableHeight - offsetTop - osbHeight;
1490
+ if (offsetTop + trHeight > tableWrapperHeight - osbHeight) {
1491
+ trHeight = tableWrapperHeight - offsetTop - osbHeight;
1470
1492
  }
1471
1493
  rdLineEl.style.display = 'block';
1472
1494
  rdLineEl.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`;
1473
1495
  rdLineEl.style.top = `${offsetTop}px`;
1474
1496
  rdLineEl.style.height = `${trHeight}px`;
1475
- rdLineEl.style.width = `${tableWidth - osbWidth}px`;
1497
+ rdLineEl.style.width = `${tableWrapperWidth - osbWidth}px`;
1476
1498
  rdLineEl.setAttribute('drag-pos', dragPos);
1477
1499
  rdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n');
1478
1500
  }
@@ -1499,7 +1521,7 @@ function showDropTip($xeTable, evnt, trEl, thEl, showLine, dragPos) {
1499
1521
  thWidth -= startX - offsetLeft;
1500
1522
  offsetLeft = startX;
1501
1523
  }
1502
- const endX = tableWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth);
1524
+ const endX = tableWrapperWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth);
1503
1525
  if (offsetLeft + thWidth > endX) {
1504
1526
  thWidth = endX - offsetLeft;
1505
1527
  }
@@ -1511,7 +1533,7 @@ function showDropTip($xeTable, evnt, trEl, thEl, showLine, dragPos) {
1511
1533
  cdLineEl.style.height = `${thRect.height}px`;
1512
1534
  }
1513
1535
  else {
1514
- cdLineEl.style.height = `${tableHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`;
1536
+ cdLineEl.style.height = `${tableWrapperHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`;
1515
1537
  }
1516
1538
  cdLineEl.setAttribute('drag-pos', dragPos);
1517
1539
  cdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n');
@@ -1587,6 +1609,20 @@ function handleScrollToRowColumn($xeTable, fieldOrColumn, row) {
1587
1609
  }
1588
1610
  return $xeTable.$nextTick();
1589
1611
  }
1612
+ const handleRowExpandReserve = ($xeTable, row, expanded) => {
1613
+ const internalData = $xeTable;
1614
+ const { rowExpandedReserveRowMap } = internalData;
1615
+ const expandOpts = $xeTable.computeExpandOpts;
1616
+ if (expandOpts.reserve) {
1617
+ const rowid = getRowid($xeTable, row);
1618
+ if (expanded) {
1619
+ rowExpandedReserveRowMap[rowid] = row;
1620
+ }
1621
+ else if (rowExpandedReserveRowMap[rowid]) {
1622
+ delete rowExpandedReserveRowMap[rowid];
1623
+ }
1624
+ }
1625
+ };
1590
1626
  // 计算可视渲染相关数据
1591
1627
  function computeScrollLoad($xeTable) {
1592
1628
  const reactData = $xeTable;
@@ -1656,14 +1692,19 @@ function handleRecalculateLayout($xeTable, reFull) {
1656
1692
  calcCellWidth($xeTable);
1657
1693
  autoCellWidth($xeTable);
1658
1694
  updateStyle($xeTable);
1695
+ if (reFull) {
1696
+ updateRowOffsetTop($xeTable);
1697
+ }
1659
1698
  updateRowExpandStyle($xeTable);
1660
1699
  return computeScrollLoad($xeTable).then(() => {
1661
1700
  if (reFull === true) {
1662
1701
  // 初始化时需要在列计算之后再执行优化运算,达到最优显示效果
1663
- calcCellHeight($xeTable);
1664
1702
  calcCellWidth($xeTable);
1665
1703
  autoCellWidth($xeTable);
1666
1704
  updateStyle($xeTable);
1705
+ if (reFull) {
1706
+ updateRowOffsetTop($xeTable);
1707
+ }
1667
1708
  updateRowExpandStyle($xeTable);
1668
1709
  return computeScrollLoad($xeTable);
1669
1710
  }
@@ -1695,16 +1736,16 @@ function handleUpdateColumn($xeTable) {
1695
1736
  function loadScrollXData($xeTable) {
1696
1737
  const reactData = $xeTable;
1697
1738
  const internalData = $xeTable;
1698
- const { mergeList, mergeFooterList } = reactData;
1739
+ const { mergeList, mergeFooterList, isScrollXBig } = reactData;
1699
1740
  const { scrollXStore } = internalData;
1700
1741
  const { preloadSize, startIndex, endIndex, offsetSize } = scrollXStore;
1701
1742
  const { toVisibleIndex, visibleSize } = handleVirtualXVisible($xeTable);
1702
1743
  const offsetItem = {
1703
- startIndex: Math.max(0, toVisibleIndex - 1 - offsetSize - preloadSize),
1704
- endIndex: toVisibleIndex + visibleSize + offsetSize + preloadSize
1744
+ startIndex: Math.max(0, isScrollXBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
1745
+ endIndex: isScrollXBig ? toVisibleIndex + visibleSize : toVisibleIndex + visibleSize + offsetSize + preloadSize
1705
1746
  };
1706
- scrollXStore.visibleStartIndex = toVisibleIndex;
1707
- scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize;
1747
+ scrollXStore.visibleStartIndex = toVisibleIndex - 1;
1748
+ scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize + 1;
1708
1749
  calculateMergerOffsetIndex(mergeList.concat(mergeFooterList), offsetItem, 'col');
1709
1750
  const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem;
1710
1751
  if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
@@ -1911,20 +1952,20 @@ function handleColumn($xeTable, collectColumn) {
1911
1952
  /**
1912
1953
  * 纵向 Y 可视渲染处理
1913
1954
  */
1914
- function loadScrollYData($xeTable, scrollTop) {
1955
+ function loadScrollYData($xeTable) {
1915
1956
  const reactData = $xeTable;
1916
1957
  const internalData = $xeTable;
1917
- const { mergeList, isAllOverflow } = reactData;
1958
+ const { mergeList, isAllOverflow, isScrollYBig } = reactData;
1918
1959
  const { scrollYStore } = internalData;
1919
1960
  const { preloadSize, startIndex, endIndex, offsetSize } = scrollYStore;
1920
1961
  const autoOffsetYSize = isAllOverflow ? offsetSize : offsetSize + 1;
1921
- const { toVisibleIndex, visibleSize } = handleVirtualYVisible($xeTable, scrollTop);
1962
+ const { toVisibleIndex, visibleSize } = handleVirtualYVisible($xeTable);
1922
1963
  const offsetItem = {
1923
- startIndex: Math.max(0, toVisibleIndex - 1 - offsetSize - preloadSize),
1924
- endIndex: toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize
1964
+ startIndex: Math.max(0, isScrollYBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
1965
+ endIndex: isScrollYBig ? (toVisibleIndex + visibleSize) : (toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize)
1925
1966
  };
1926
- scrollYStore.visibleStartIndex = toVisibleIndex;
1927
- scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize;
1967
+ scrollYStore.visibleStartIndex = toVisibleIndex - 1;
1968
+ scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize + 1;
1928
1969
  calculateMergerOffsetIndex(mergeList, offsetItem, 'row');
1929
1970
  const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem;
1930
1971
  if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
@@ -2110,6 +2151,40 @@ function handleUpdateRowResize($xeTable, evnt, params) {
2110
2151
  setTimeout(() => $xeTable.recalculate(true), 300);
2111
2152
  });
2112
2153
  }
2154
+ function updateColumnOffsetLeft($xeTable) {
2155
+ const internalData = $xeTable;
2156
+ const { visibleColumn, fullColumnIdData } = internalData;
2157
+ let offsetLeft = 0;
2158
+ for (let cIndex = 0, rLen = visibleColumn.length; cIndex < rLen; cIndex++) {
2159
+ const column = visibleColumn[cIndex];
2160
+ const colid = column.id;
2161
+ const colRest = fullColumnIdData[colid];
2162
+ colRest.oLeft = offsetLeft;
2163
+ offsetLeft += column.renderWidth;
2164
+ }
2165
+ }
2166
+ function updateRowOffsetTop($xeTable) {
2167
+ const reactData = $xeTable;
2168
+ const internalData = $xeTable;
2169
+ const { expandColumn, rowExpandedMaps } = reactData;
2170
+ const { afterFullData, fullAllDataRowIdData } = internalData;
2171
+ const expandOpts = $xeTable.computeExpandOpts;
2172
+ const rowOpts = $xeTable.computeRowOpts;
2173
+ const cellOpts = $xeTable.computeCellOpts;
2174
+ const defaultRowHeight = $xeTable.computeDefaultRowHeight;
2175
+ let offsetTop = 0;
2176
+ for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
2177
+ const row = afterFullData[rIndex];
2178
+ const rowid = getRowid($xeTable, row);
2179
+ const rowRest = fullAllDataRowIdData[rowid] || {};
2180
+ rowRest.oTop = offsetTop;
2181
+ offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
2182
+ // 是否展开行
2183
+ if (expandColumn && rowExpandedMaps[rowid]) {
2184
+ offsetTop += rowRest.expandHeight || expandOpts.height || 0;
2185
+ }
2186
+ }
2187
+ }
2113
2188
  function updateRowExpandStyle($xeTable) {
2114
2189
  const reactData = $xeTable;
2115
2190
  const internalData = $xeTable;
@@ -4060,7 +4135,7 @@ const Methods = {
4060
4135
  resizeBarElem.style.height = `${scrollbarXToTop ? tableHeight - osbHeight : tableHeight}px`;
4061
4136
  if (resizableOpts.showDragTip && resizeTipElem) {
4062
4137
  resizeTipElem.textContent = getI18n('vxe.table.resizeColTip', [resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)]);
4063
- const tableWidth = tableEl.clientWidth;
4138
+ const tableWrapperWidth = tableEl.clientWidth;
4064
4139
  const wrapperRect = wrapperElem.getBoundingClientRect();
4065
4140
  const resizeBarWidth = resizeBarElem.clientWidth;
4066
4141
  const resizeTipWidth = resizeTipElem.clientWidth;
@@ -4069,8 +4144,8 @@ const Methods = {
4069
4144
  if (resizeBarLeft < resizeTipWidth + resizeBarWidth) {
4070
4145
  resizeTipLeft = 0;
4071
4146
  }
4072
- else if (resizeBarLeft > tableWidth) {
4073
- resizeTipLeft += tableWidth - resizeBarLeft;
4147
+ else if (resizeBarLeft > tableWrapperWidth) {
4148
+ resizeTipLeft += tableWrapperWidth - resizeBarLeft;
4074
4149
  }
4075
4150
  resizeTipElem.style.left = `${resizeTipLeft}px`;
4076
4151
  resizeTipElem.style.top = `${Math.min(tableHeight - resizeTipHeight, Math.max(0, evnt.clientY - wrapperRect.y - resizeTipHeight / 2))}px`;
@@ -4208,7 +4283,7 @@ const Methods = {
4208
4283
  const updateEvent = (evnt) => {
4209
4284
  evnt.stopPropagation();
4210
4285
  evnt.preventDefault();
4211
- const tableWidth = tableEl.clientWidth - osbWidth;
4286
+ const rtWidth = tableEl.clientWidth - osbWidth;
4212
4287
  const tableHeight = tableEl.clientHeight - osbHeight;
4213
4288
  let dragTop = evnt.clientY - tableRect.y - targetOffsetY;
4214
4289
  if (dragTop < minTop) {
@@ -4219,15 +4294,15 @@ const Methods = {
4219
4294
  }
4220
4295
  resizeBarElem.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`;
4221
4296
  resizeBarElem.style.top = `${dragTop}px`;
4222
- resizeBarElem.style.width = `${tableWidth}px`;
4297
+ resizeBarElem.style.width = `${rtWidth}px`;
4223
4298
  if (resizableOpts.showDragTip && resizeTipElem) {
4224
4299
  resizeTipElem.textContent = getI18n('vxe.table.resizeRowTip', [resizeHeight]);
4225
4300
  const resizeTipWidth = resizeTipElem.clientWidth;
4226
4301
  const resizeTipHeight = resizeTipElem.clientHeight;
4227
4302
  let resizeBarLeft = Math.max(2, evnt.clientX - tableRect.x);
4228
4303
  let resizeBarTop = 0;
4229
- if (resizeBarLeft + resizeTipWidth >= tableWidth - 2) {
4230
- resizeBarLeft = tableWidth - resizeTipWidth - 2;
4304
+ if (resizeBarLeft + resizeTipWidth >= rtWidth - 2) {
4305
+ resizeBarLeft = rtWidth - resizeTipWidth - 2;
4231
4306
  }
4232
4307
  if (dragTop + resizeTipHeight >= tableHeight) {
4233
4308
  resizeBarTop = tableHeight - (dragTop + resizeTipHeight);
@@ -4258,6 +4333,7 @@ const Methods = {
4258
4333
  else {
4259
4334
  rowRest.resizeHeight = resizeHeight;
4260
4335
  handleUpdateRowResize($xeTable, evnt, resizeParams);
4336
+ updateRowOffsetTop($xeTable);
4261
4337
  }
4262
4338
  }
4263
4339
  removeClass(tableEl, 'row-drag--resize');
@@ -5588,8 +5664,8 @@ const Methods = {
5588
5664
  const { treeConfig } = props;
5589
5665
  const { selectCheckboxMaps, treeIndeterminateMaps } = reactData;
5590
5666
  const checkboxOpts = $xeTable.computeCheckboxOpts;
5591
- const { checkField, checkMethod } = checkboxOpts;
5592
- const { afterFullData, afterTreeFullData } = internalData;
5667
+ const { checkField, checkMethod, showReserveStatus } = checkboxOpts;
5668
+ const { afterFullData, afterTreeFullData, checkboxReserveRowMap } = internalData;
5593
5669
  let sLen = 0; // 已选
5594
5670
  let hLen = 0; // 半选
5595
5671
  let vLen = 0; // 有效行
@@ -5628,7 +5704,11 @@ const Methods = {
5628
5704
  vLen++;
5629
5705
  });
5630
5706
  const isSelected = rootList.length > 0 ? (vLen > 0 ? (sLen >= vLen) : (sLen >= rootList.length)) : false;
5631
- const halfSelect = !isSelected && (sLen >= 1 || hLen >= 1);
5707
+ let halfSelect = !isSelected && (sLen >= 1 || hLen >= 1);
5708
+ // 如果复选框启用保留记录,当保留数据存在时显示半选
5709
+ if (!isSelected && !halfSelect && showReserveStatus) {
5710
+ halfSelect = !XEUtils.isEmpty(checkboxReserveRowMap);
5711
+ }
5632
5712
  reactData.isAllSelected = isSelected;
5633
5713
  reactData.isIndeterminate = halfSelect;
5634
5714
  },
@@ -6895,22 +6975,22 @@ const Methods = {
6895
6975
  const scrollTargetEl = xHandleEl || tableBodyElem;
6896
6976
  if (scrollTargetEl) {
6897
6977
  const wrapperRect = el.getBoundingClientRect();
6898
- const tableWidth = el.clientWidth;
6978
+ const tableWrapperWidth = el.clientWidth;
6899
6979
  const leftContainerElem = $xeTable.$refs.refLeftContainer;
6900
6980
  const leftContainerWidth = leftContainerElem ? leftContainerElem.clientWidth : 0;
6901
6981
  const rightContainerElem = $xeTable.$refs.refRightContainer;
6902
6982
  const rightContainerWidth = rightContainerElem ? rightContainerElem.clientWidth : 0;
6903
6983
  const srartX = wrapperRect.x + leftContainerWidth;
6904
- const endX = wrapperRect.x + tableWidth - rightContainerWidth;
6984
+ const endX = wrapperRect.x + tableWrapperWidth - rightContainerWidth;
6905
6985
  const distSize = 28;
6906
6986
  const startDistSize = clientX - srartX;
6907
6987
  const endDistSize = endX - clientX;
6908
6988
  if (startDistSize > 0 && startDistSize <= distSize) {
6909
- const scrollRatio = Math.floor(tableWidth / (startDistSize > distSize / 2 ? 240 : 120));
6989
+ const scrollRatio = Math.floor(tableWrapperWidth / (startDistSize > distSize / 2 ? 240 : 120));
6910
6990
  scrollTargetEl.scrollLeft -= scrollRatio * (distSize - startDistSize);
6911
6991
  }
6912
6992
  else if (endDistSize > 0 && endDistSize <= distSize) {
6913
- const scrollRatio = Math.floor(tableWidth / (endDistSize > distSize / 2 ? 240 : 120));
6993
+ const scrollRatio = Math.floor(tableWrapperWidth / (endDistSize > distSize / 2 ? 240 : 120));
6914
6994
  scrollTargetEl.scrollLeft += scrollRatio * (distSize - endDistSize);
6915
6995
  }
6916
6996
  }
@@ -7406,17 +7486,17 @@ const Methods = {
7406
7486
  });
7407
7487
  }
7408
7488
  if (reserve) {
7409
- validRows.forEach((row) => this.handleRowExpandReserve(row, expanded));
7489
+ validRows.forEach((row) => handleRowExpandReserve($xeTable, row, expanded));
7410
7490
  }
7411
7491
  }
7412
7492
  this.rowExpandedMaps = rExpandedMaps;
7413
7493
  return Promise.all(lazyRests)
7414
- .then(() => $xeTable.recalculate())
7494
+ .then(() => $xeTable.$nextTick())
7495
+ .then(() => $xeTable.recalculate(true))
7415
7496
  .then(() => {
7416
- if (expandColumn) {
7417
- updateRowExpandStyle($xeTable);
7418
- handleRowExpandScroll($xeTable);
7419
- }
7497
+ updateRowOffsetTop($xeTable);
7498
+ updateRowExpandStyle($xeTable);
7499
+ handleRowExpandScroll($xeTable);
7420
7500
  return $xeTable.updateCellAreas();
7421
7501
  });
7422
7502
  },
@@ -7441,35 +7521,31 @@ const Methods = {
7441
7521
  */
7442
7522
  clearRowExpand() {
7443
7523
  const $xeTable = this;
7444
- const { expandOpts, tableFullData } = this;
7524
+ const reactData = $xeTable;
7525
+ const internalData = $xeTable;
7526
+ const { tableFullData } = internalData;
7527
+ const expandOpts = $xeTable.computeExpandOpts;
7445
7528
  const { reserve } = expandOpts;
7446
- const expList = this.getRowExpandRecords();
7447
- this.rowExpandedMaps = {};
7529
+ const expList = $xeTable.getRowExpandRecords();
7530
+ reactData.rowExpandedMaps = {};
7448
7531
  if (reserve) {
7449
- tableFullData.forEach((row) => this.handleRowExpandReserve(row, false));
7532
+ tableFullData.forEach((row) => handleRowExpandReserve($xeTable, row, false));
7450
7533
  }
7451
- return this.$nextTick().then(() => {
7534
+ return $xeTable.$nextTick().then(() => {
7452
7535
  if (expList.length) {
7453
- this.recalculate();
7536
+ return $xeTable.recalculate(true);
7454
7537
  }
7455
- }).then(() => $xeTable.updateCellAreas());
7538
+ }).then(() => {
7539
+ updateRowOffsetTop($xeTable);
7540
+ updateRowExpandStyle($xeTable);
7541
+ handleRowExpandScroll($xeTable);
7542
+ return $xeTable.updateCellAreas();
7543
+ });
7456
7544
  },
7457
7545
  clearRowExpandReserve() {
7458
7546
  this.rowExpandedReserveRowMap = {};
7459
7547
  return this.$nextTick();
7460
7548
  },
7461
- handleRowExpandReserve(row, expanded) {
7462
- const { rowExpandedReserveRowMap, expandOpts } = this;
7463
- if (expandOpts.reserve) {
7464
- const rowid = getRowid(this, row);
7465
- if (expanded) {
7466
- rowExpandedReserveRowMap[rowid] = row;
7467
- }
7468
- else if (rowExpandedReserveRowMap[rowid]) {
7469
- delete rowExpandedReserveRowMap[rowid];
7470
- }
7471
- }
7472
- },
7473
7549
  getRowExpandRecords() {
7474
7550
  const rest = [];
7475
7551
  XEUtils.each(this.rowExpandedMaps, item => {
@@ -8352,43 +8428,66 @@ const Methods = {
8352
8428
  const $xeTable = this;
8353
8429
  const reactData = $xeTable;
8354
8430
  const internalData = $xeTable;
8355
- const { isGroup, scrollXLoad } = reactData;
8356
- const { visibleColumn, scrollXStore, elemStore, tableWidth } = internalData;
8357
- const tableHeader = $xeTable.$refs.refTableHeader;
8431
+ const { isGroup, scrollXLoad, overflowX, scrollXWidth } = reactData;
8432
+ const { visibleColumn, scrollXStore, elemStore, fullColumnIdData } = internalData;
8358
8433
  const tableBody = $xeTable.$refs.refTableBody;
8359
- const tableFooter = $xeTable.$refs.refTableFooter;
8360
8434
  const tableBodyElem = tableBody ? tableBody.$el : null;
8361
8435
  if (tableBodyElem) {
8362
- const tableHeaderElem = tableHeader ? tableHeader.$el : null;
8363
- const tableFooterElem = tableFooter ? tableFooter.$el : null;
8364
- const headerElem = tableHeaderElem ? tableHeaderElem.querySelector('.vxe-table--header') : null;
8365
- const bodyElem = tableBodyElem.querySelector('.vxe-table--body');
8366
- const footerElem = tableFooterElem ? tableFooterElem.querySelector('.vxe-table--footer') : null;
8367
- const leftSpaceWidth = visibleColumn.slice(0, scrollXStore.startIndex).reduce((previous, column) => previous + column.renderWidth, 0);
8436
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
8437
+ const bodyTableElem = getRefElem(elemStore['main-body-table']);
8438
+ const headerTableElem = getRefElem(elemStore['main-header-table']);
8439
+ const footerTableElem = getRefElem(elemStore['main-footer-table']);
8440
+ let xSpaceLeft = 0;
8441
+ const firstColumn = visibleColumn[scrollXStore.startIndex];
8442
+ if (firstColumn) {
8443
+ const colRest = fullColumnIdData[firstColumn.id] || {};
8444
+ xSpaceLeft = colRest.oLeft;
8445
+ }
8446
+ let clientWidth = 0;
8447
+ if (bodyScrollElem) {
8448
+ clientWidth = bodyScrollElem.clientWidth;
8449
+ }
8450
+ // 虚拟渲染
8451
+ let isScrollXBig = false;
8452
+ let ySpaceWidth = scrollXWidth;
8453
+ if (scrollXWidth > maxXWidth) {
8454
+ // 触右
8455
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
8456
+ xSpaceLeft = maxXWidth - bodyTableElem.clientWidth;
8457
+ }
8458
+ else {
8459
+ xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth));
8460
+ }
8461
+ ySpaceWidth = maxXWidth;
8462
+ isScrollXBig = true;
8463
+ }
8368
8464
  let marginLeft = '';
8369
- if (scrollXLoad) {
8370
- marginLeft = `${leftSpaceWidth}px`;
8465
+ if (scrollXLoad && overflowX) {
8466
+ marginLeft = `${xSpaceLeft}px`;
8371
8467
  }
8372
- if (headerElem) {
8373
- headerElem.style.marginLeft = isGroup ? '' : marginLeft;
8468
+ if (headerTableElem) {
8469
+ headerTableElem.style.marginLeft = isGroup ? '' : marginLeft;
8374
8470
  }
8375
- bodyElem.style.marginLeft = marginLeft;
8376
- if (footerElem) {
8377
- footerElem.style.marginLeft = marginLeft;
8471
+ if (bodyTableElem) {
8472
+ bodyTableElem.style.marginLeft = marginLeft;
8473
+ }
8474
+ if (footerTableElem) {
8475
+ footerTableElem.style.marginLeft = marginLeft;
8378
8476
  }
8477
+ reactData.isScrollXBig = isScrollXBig;
8379
8478
  const containerList = ['main'];
8380
8479
  containerList.forEach(name => {
8381
8480
  const layoutList = ['header', 'body', 'footer'];
8382
8481
  layoutList.forEach(layout => {
8383
8482
  const xSpaceElem = getRefElem(elemStore[`${name}-${layout}-xSpace`]);
8384
8483
  if (xSpaceElem) {
8385
- xSpaceElem.style.width = scrollXLoad ? `${tableWidth}px` : '';
8484
+ xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : '';
8386
8485
  }
8387
8486
  });
8388
8487
  });
8389
8488
  const scrollXSpaceEl = $xeTable.$refs.refScrollXSpaceElem;
8390
8489
  if (scrollXSpaceEl) {
8391
- scrollXSpaceEl.style.width = `${tableWidth}px`;
8490
+ scrollXSpaceEl.style.width = `${ySpaceWidth}px`;
8392
8491
  }
8393
8492
  $xeTable.$nextTick(() => {
8394
8493
  updateStyle($xeTable);
@@ -8416,49 +8515,66 @@ const Methods = {
8416
8515
  const rowOpts = $xeTable.computeRowOpts;
8417
8516
  const cellOpts = $xeTable.computeCellOpts;
8418
8517
  const defaultRowHeight = $xeTable.computeDefaultRowHeight;
8518
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
8419
8519
  const bodyTableElem = getRefElem(elemStore['main-body-table']);
8420
8520
  const containerList = ['main', 'left', 'right'];
8421
- let topSpaceHeight = 0;
8422
- let ySpaceHeight = 0;
8521
+ let ySpaceTop = 0;
8522
+ let scrollYHeight = 0;
8523
+ let isScrollYBig = false;
8423
8524
  if (scrollYLoad) {
8424
8525
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height;
8425
8526
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
8426
- ySpaceHeight = afterFullData.length * defaultRowHeight;
8427
- topSpaceHeight = Math.max(0, startIndex * defaultRowHeight);
8527
+ scrollYHeight = afterFullData.length * defaultRowHeight;
8528
+ if (scrollYHeight > maxYHeight) {
8529
+ isScrollYBig = true;
8530
+ }
8531
+ ySpaceTop = Math.max(0, startIndex * defaultRowHeight);
8428
8532
  }
8429
8533
  else {
8430
- for (let i = 0; i < afterFullData.length; i++) {
8431
- const row = afterFullData[i];
8432
- const rowid = getRowid($xeTable, row);
8433
- const rowRest = fullAllDataRowIdData[rowid] || {};
8434
- ySpaceHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
8435
- // 是否展开行
8436
- if (expandColumn && rowExpandedMaps[rowid]) {
8437
- ySpaceHeight += rowRest.expandHeight || expandOpts.height || 0;
8438
- }
8534
+ const firstRow = afterFullData[startIndex];
8535
+ let rowid = getRowid($xeTable, firstRow);
8536
+ let rowRest = fullAllDataRowIdData[rowid] || {};
8537
+ ySpaceTop = rowRest.oTop;
8538
+ const lastRow = afterFullData[afterFullData.length - 1];
8539
+ rowid = getRowid($xeTable, lastRow);
8540
+ rowRest = fullAllDataRowIdData[rowid] || {};
8541
+ scrollYHeight = rowRest.oTop + (rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight);
8542
+ // 是否展开行
8543
+ if (expandColumn && rowExpandedMaps[rowid]) {
8544
+ scrollYHeight += rowRest.expandHeight || expandOpts.height || 0;
8439
8545
  }
8440
- for (let i = 0; i < startIndex; i++) {
8441
- const row = afterFullData[i];
8442
- const rowid = getRowid($xeTable, row);
8443
- const rowRest = fullAllDataRowIdData[rowid] || {};
8444
- topSpaceHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight;
8445
- // 是否展开行
8446
- if (expandColumn && rowExpandedMaps[rowid]) {
8447
- topSpaceHeight += rowRest.expandHeight || expandOpts.height || 0;
8448
- }
8546
+ if (scrollYHeight > maxYHeight) {
8547
+ isScrollYBig = true;
8449
8548
  }
8450
8549
  }
8451
8550
  }
8452
8551
  else {
8453
8552
  if (bodyTableElem) {
8454
- ySpaceHeight = bodyTableElem.clientHeight;
8553
+ scrollYHeight = bodyTableElem.clientHeight;
8554
+ }
8555
+ }
8556
+ let clientHeight = 0;
8557
+ if (bodyScrollElem) {
8558
+ clientHeight = bodyScrollElem.clientHeight;
8559
+ }
8560
+ // 虚拟渲染
8561
+ let ySpaceHeight = scrollYHeight;
8562
+ let scrollYTop = ySpaceTop;
8563
+ if (isScrollYBig) {
8564
+ // 触底
8565
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
8566
+ scrollYTop = maxYHeight - bodyTableElem.clientHeight;
8567
+ }
8568
+ else {
8569
+ scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight));
8455
8570
  }
8571
+ ySpaceHeight = maxYHeight;
8456
8572
  }
8457
8573
  containerList.forEach(name => {
8458
8574
  const layoutList = ['header', 'body', 'footer'];
8459
8575
  const tableElem = getRefElem(elemStore[`${name}-body-table`]);
8460
8576
  if (tableElem) {
8461
- tableElem.style.marginTop = topSpaceHeight ? `${topSpaceHeight}px` : '';
8577
+ tableElem.style.marginTop = scrollYTop ? `${scrollYTop}px` : '';
8462
8578
  }
8463
8579
  layoutList.forEach(layout => {
8464
8580
  const ySpaceElem = getRefElem(elemStore[`${name}-${layout}-ySpace`]);
@@ -8475,6 +8591,9 @@ const Methods = {
8475
8591
  if (rowExpandYSpaceEl) {
8476
8592
  rowExpandYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
8477
8593
  }
8594
+ reactData.scrollYTop = scrollYTop;
8595
+ reactData.scrollYHeight = scrollYHeight;
8596
+ reactData.isScrollYBig = isScrollYBig;
8478
8597
  return $xeTable.$nextTick().then(() => {
8479
8598
  updateStyle($xeTable);
8480
8599
  });