vxe-table 3.13.15 → 3.14.0-beta.0

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/edit/mixin.js +3 -1
  4. package/es/table/src/methods.js +275 -160
  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 +1595 -2542
  11. package/lib/index.umd.min.js +1 -1
  12. package/lib/style.css +1 -1
  13. package/lib/table/module/edit/mixin.js +3 -1
  14. package/lib/table/module/edit/mixin.min.js +1 -1
  15. package/lib/table/src/methods.js +289 -166
  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/edit/mixin.ts +3 -1
  26. package/packages/table/src/methods.ts +286 -164
  27. package/packages/table/src/table.ts +55 -53
  28. /package/es/{iconfont.1740723810366.ttf → iconfont.1740732119954.ttf} +0 -0
  29. /package/es/{iconfont.1740723810366.woff → iconfont.1740732119954.woff} +0 -0
  30. /package/es/{iconfont.1740723810366.woff2 → iconfont.1740732119954.woff2} +0 -0
  31. /package/lib/{iconfont.1740723810366.ttf → iconfont.1740732119954.ttf} +0 -0
  32. /package/lib/{iconfont.1740723810366.woff → iconfont.1740732119954.woff} +0 -0
  33. /package/lib/{iconfont.1740723810366.woff2 → iconfont.1740732119954.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');
@@ -6895,22 +6971,22 @@ const Methods = {
6895
6971
  const scrollTargetEl = xHandleEl || tableBodyElem;
6896
6972
  if (scrollTargetEl) {
6897
6973
  const wrapperRect = el.getBoundingClientRect();
6898
- const tableWidth = el.clientWidth;
6974
+ const tableWrapperWidth = el.clientWidth;
6899
6975
  const leftContainerElem = $xeTable.$refs.refLeftContainer;
6900
6976
  const leftContainerWidth = leftContainerElem ? leftContainerElem.clientWidth : 0;
6901
6977
  const rightContainerElem = $xeTable.$refs.refRightContainer;
6902
6978
  const rightContainerWidth = rightContainerElem ? rightContainerElem.clientWidth : 0;
6903
6979
  const srartX = wrapperRect.x + leftContainerWidth;
6904
- const endX = wrapperRect.x + tableWidth - rightContainerWidth;
6980
+ const endX = wrapperRect.x + tableWrapperWidth - rightContainerWidth;
6905
6981
  const distSize = 28;
6906
6982
  const startDistSize = clientX - srartX;
6907
6983
  const endDistSize = endX - clientX;
6908
6984
  if (startDistSize > 0 && startDistSize <= distSize) {
6909
- const scrollRatio = Math.floor(tableWidth / (startDistSize > distSize / 2 ? 240 : 120));
6985
+ const scrollRatio = Math.floor(tableWrapperWidth / (startDistSize > distSize / 2 ? 240 : 120));
6910
6986
  scrollTargetEl.scrollLeft -= scrollRatio * (distSize - startDistSize);
6911
6987
  }
6912
6988
  else if (endDistSize > 0 && endDistSize <= distSize) {
6913
- const scrollRatio = Math.floor(tableWidth / (endDistSize > distSize / 2 ? 240 : 120));
6989
+ const scrollRatio = Math.floor(tableWrapperWidth / (endDistSize > distSize / 2 ? 240 : 120));
6914
6990
  scrollTargetEl.scrollLeft += scrollRatio * (distSize - endDistSize);
6915
6991
  }
6916
6992
  }
@@ -7406,17 +7482,17 @@ const Methods = {
7406
7482
  });
7407
7483
  }
7408
7484
  if (reserve) {
7409
- validRows.forEach((row) => this.handleRowExpandReserve(row, expanded));
7485
+ validRows.forEach((row) => handleRowExpandReserve($xeTable, row, expanded));
7410
7486
  }
7411
7487
  }
7412
7488
  this.rowExpandedMaps = rExpandedMaps;
7413
7489
  return Promise.all(lazyRests)
7414
- .then(() => $xeTable.recalculate())
7490
+ .then(() => $xeTable.$nextTick())
7491
+ .then(() => $xeTable.recalculate(true))
7415
7492
  .then(() => {
7416
- if (expandColumn) {
7417
- updateRowExpandStyle($xeTable);
7418
- handleRowExpandScroll($xeTable);
7419
- }
7493
+ updateRowOffsetTop($xeTable);
7494
+ updateRowExpandStyle($xeTable);
7495
+ handleRowExpandScroll($xeTable);
7420
7496
  return $xeTable.updateCellAreas();
7421
7497
  });
7422
7498
  },
@@ -7441,35 +7517,31 @@ const Methods = {
7441
7517
  */
7442
7518
  clearRowExpand() {
7443
7519
  const $xeTable = this;
7444
- const { expandOpts, tableFullData } = this;
7520
+ const reactData = $xeTable;
7521
+ const internalData = $xeTable;
7522
+ const { tableFullData } = internalData;
7523
+ const expandOpts = $xeTable.computeExpandOpts;
7445
7524
  const { reserve } = expandOpts;
7446
- const expList = this.getRowExpandRecords();
7447
- this.rowExpandedMaps = {};
7525
+ const expList = $xeTable.getRowExpandRecords();
7526
+ reactData.rowExpandedMaps = {};
7448
7527
  if (reserve) {
7449
- tableFullData.forEach((row) => this.handleRowExpandReserve(row, false));
7528
+ tableFullData.forEach((row) => handleRowExpandReserve($xeTable, row, false));
7450
7529
  }
7451
- return this.$nextTick().then(() => {
7530
+ return $xeTable.$nextTick().then(() => {
7452
7531
  if (expList.length) {
7453
- this.recalculate();
7532
+ return $xeTable.recalculate(true);
7454
7533
  }
7455
- }).then(() => $xeTable.updateCellAreas());
7534
+ }).then(() => {
7535
+ updateRowOffsetTop($xeTable);
7536
+ updateRowExpandStyle($xeTable);
7537
+ handleRowExpandScroll($xeTable);
7538
+ return $xeTable.updateCellAreas();
7539
+ });
7456
7540
  },
7457
7541
  clearRowExpandReserve() {
7458
7542
  this.rowExpandedReserveRowMap = {};
7459
7543
  return this.$nextTick();
7460
7544
  },
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
7545
  getRowExpandRecords() {
7474
7546
  const rest = [];
7475
7547
  XEUtils.each(this.rowExpandedMaps, item => {
@@ -8352,43 +8424,66 @@ const Methods = {
8352
8424
  const $xeTable = this;
8353
8425
  const reactData = $xeTable;
8354
8426
  const internalData = $xeTable;
8355
- const { isGroup, scrollXLoad } = reactData;
8356
- const { visibleColumn, scrollXStore, elemStore, tableWidth } = internalData;
8357
- const tableHeader = $xeTable.$refs.refTableHeader;
8427
+ const { isGroup, scrollXLoad, overflowX, scrollXWidth } = reactData;
8428
+ const { visibleColumn, scrollXStore, elemStore, fullColumnIdData } = internalData;
8358
8429
  const tableBody = $xeTable.$refs.refTableBody;
8359
- const tableFooter = $xeTable.$refs.refTableFooter;
8360
8430
  const tableBodyElem = tableBody ? tableBody.$el : null;
8361
8431
  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);
8432
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
8433
+ const bodyTableElem = getRefElem(elemStore['main-body-table']);
8434
+ const headerTableElem = getRefElem(elemStore['main-header-table']);
8435
+ const footerTableElem = getRefElem(elemStore['main-footer-table']);
8436
+ let xSpaceLeft = 0;
8437
+ const firstColumn = visibleColumn[scrollXStore.startIndex];
8438
+ if (firstColumn) {
8439
+ const colRest = fullColumnIdData[firstColumn.id] || {};
8440
+ xSpaceLeft = colRest.oLeft;
8441
+ }
8442
+ let clientWidth = 0;
8443
+ if (bodyScrollElem) {
8444
+ clientWidth = bodyScrollElem.clientWidth;
8445
+ }
8446
+ // 虚拟渲染
8447
+ let isScrollXBig = false;
8448
+ let ySpaceWidth = scrollXWidth;
8449
+ if (scrollXWidth > maxXWidth) {
8450
+ // 触右
8451
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
8452
+ xSpaceLeft = maxXWidth - bodyTableElem.clientWidth;
8453
+ }
8454
+ else {
8455
+ xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth));
8456
+ }
8457
+ ySpaceWidth = maxXWidth;
8458
+ isScrollXBig = true;
8459
+ }
8368
8460
  let marginLeft = '';
8369
- if (scrollXLoad) {
8370
- marginLeft = `${leftSpaceWidth}px`;
8461
+ if (scrollXLoad && overflowX) {
8462
+ marginLeft = `${xSpaceLeft}px`;
8371
8463
  }
8372
- if (headerElem) {
8373
- headerElem.style.marginLeft = isGroup ? '' : marginLeft;
8464
+ if (headerTableElem) {
8465
+ headerTableElem.style.marginLeft = isGroup ? '' : marginLeft;
8374
8466
  }
8375
- bodyElem.style.marginLeft = marginLeft;
8376
- if (footerElem) {
8377
- footerElem.style.marginLeft = marginLeft;
8467
+ if (bodyTableElem) {
8468
+ bodyTableElem.style.marginLeft = marginLeft;
8469
+ }
8470
+ if (footerTableElem) {
8471
+ footerTableElem.style.marginLeft = marginLeft;
8378
8472
  }
8473
+ reactData.isScrollXBig = isScrollXBig;
8379
8474
  const containerList = ['main'];
8380
8475
  containerList.forEach(name => {
8381
8476
  const layoutList = ['header', 'body', 'footer'];
8382
8477
  layoutList.forEach(layout => {
8383
8478
  const xSpaceElem = getRefElem(elemStore[`${name}-${layout}-xSpace`]);
8384
8479
  if (xSpaceElem) {
8385
- xSpaceElem.style.width = scrollXLoad ? `${tableWidth}px` : '';
8480
+ xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : '';
8386
8481
  }
8387
8482
  });
8388
8483
  });
8389
8484
  const scrollXSpaceEl = $xeTable.$refs.refScrollXSpaceElem;
8390
8485
  if (scrollXSpaceEl) {
8391
- scrollXSpaceEl.style.width = `${tableWidth}px`;
8486
+ scrollXSpaceEl.style.width = `${ySpaceWidth}px`;
8392
8487
  }
8393
8488
  $xeTable.$nextTick(() => {
8394
8489
  updateStyle($xeTable);
@@ -8416,49 +8511,66 @@ const Methods = {
8416
8511
  const rowOpts = $xeTable.computeRowOpts;
8417
8512
  const cellOpts = $xeTable.computeCellOpts;
8418
8513
  const defaultRowHeight = $xeTable.computeDefaultRowHeight;
8514
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll']);
8419
8515
  const bodyTableElem = getRefElem(elemStore['main-body-table']);
8420
8516
  const containerList = ['main', 'left', 'right'];
8421
- let topSpaceHeight = 0;
8422
- let ySpaceHeight = 0;
8517
+ let ySpaceTop = 0;
8518
+ let scrollYHeight = 0;
8519
+ let isScrollYBig = false;
8423
8520
  if (scrollYLoad) {
8424
8521
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height;
8425
8522
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
8426
- ySpaceHeight = afterFullData.length * defaultRowHeight;
8427
- topSpaceHeight = Math.max(0, startIndex * defaultRowHeight);
8523
+ scrollYHeight = afterFullData.length * defaultRowHeight;
8524
+ if (scrollYHeight > maxYHeight) {
8525
+ isScrollYBig = true;
8526
+ }
8527
+ ySpaceTop = Math.max(0, startIndex * defaultRowHeight);
8428
8528
  }
8429
8529
  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
- }
8530
+ const firstRow = afterFullData[startIndex];
8531
+ let rowid = getRowid($xeTable, firstRow);
8532
+ let rowRest = fullAllDataRowIdData[rowid] || {};
8533
+ ySpaceTop = rowRest.oTop;
8534
+ const lastRow = afterFullData[afterFullData.length - 1];
8535
+ rowid = getRowid($xeTable, lastRow);
8536
+ rowRest = fullAllDataRowIdData[rowid] || {};
8537
+ scrollYHeight = rowRest.oTop + (rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight);
8538
+ // 是否展开行
8539
+ if (expandColumn && rowExpandedMaps[rowid]) {
8540
+ scrollYHeight += rowRest.expandHeight || expandOpts.height || 0;
8439
8541
  }
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
- }
8542
+ if (scrollYHeight > maxYHeight) {
8543
+ isScrollYBig = true;
8449
8544
  }
8450
8545
  }
8451
8546
  }
8452
8547
  else {
8453
8548
  if (bodyTableElem) {
8454
- ySpaceHeight = bodyTableElem.clientHeight;
8549
+ scrollYHeight = bodyTableElem.clientHeight;
8550
+ }
8551
+ }
8552
+ let clientHeight = 0;
8553
+ if (bodyScrollElem) {
8554
+ clientHeight = bodyScrollElem.clientHeight;
8555
+ }
8556
+ // 虚拟渲染
8557
+ let ySpaceHeight = scrollYHeight;
8558
+ let scrollYTop = ySpaceTop;
8559
+ if (isScrollYBig) {
8560
+ // 触底
8561
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
8562
+ scrollYTop = maxYHeight - bodyTableElem.clientHeight;
8563
+ }
8564
+ else {
8565
+ scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight));
8455
8566
  }
8567
+ ySpaceHeight = maxYHeight;
8456
8568
  }
8457
8569
  containerList.forEach(name => {
8458
8570
  const layoutList = ['header', 'body', 'footer'];
8459
8571
  const tableElem = getRefElem(elemStore[`${name}-body-table`]);
8460
8572
  if (tableElem) {
8461
- tableElem.style.marginTop = topSpaceHeight ? `${topSpaceHeight}px` : '';
8573
+ tableElem.style.marginTop = scrollYTop ? `${scrollYTop}px` : '';
8462
8574
  }
8463
8575
  layoutList.forEach(layout => {
8464
8576
  const ySpaceElem = getRefElem(elemStore[`${name}-${layout}-ySpace`]);
@@ -8475,6 +8587,9 @@ const Methods = {
8475
8587
  if (rowExpandYSpaceEl) {
8476
8588
  rowExpandYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : '';
8477
8589
  }
8590
+ reactData.scrollYTop = scrollYTop;
8591
+ reactData.scrollYHeight = scrollYHeight;
8592
+ reactData.isScrollYBig = isScrollYBig;
8478
8593
  return $xeTable.$nextTick().then(() => {
8479
8594
  updateStyle($xeTable);
8480
8595
  });