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
@@ -12,6 +12,8 @@ import type { VxeTableDefines, VxeColumnPropTypes, VxeTableEmits, ValueOf, Table
12
12
  const { getConfig, getI18n, renderer, formats, interceptor, createEvent } = VxeUI
13
13
 
14
14
  const customStorageKey = 'VXE_CUSTOM_STORE'
15
+ const maxYHeight = 5e6
16
+ const maxXWidth = 5e6
15
17
 
16
18
  function eqCellValue (row1: any, row2: any, field: any) {
17
19
  const val1 = XEUtils.get(row1, field)
@@ -74,29 +76,44 @@ function handleReserveRow ($xeTable: VxeTableConstructor & VxeTablePrivateMethod
74
76
  }
75
77
 
76
78
  function handleVirtualXVisible ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
79
+ const reactData = $xeTable as unknown as TableReactData
77
80
  const internalData = $xeTable as unknown as TableInternalData
78
81
 
79
- const { elemStore, visibleColumn } = internalData
82
+ const { isScrollXBig, scrollXWidth } = reactData
83
+ const { elemStore, visibleColumn, fullColumnIdData } = internalData
80
84
  const leftFixedWidth = $xeTable.computeLeftFixedWidth
81
85
  const rightFixedWidth = $xeTable.computeRightFixedWidth
82
86
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
83
87
  if (bodyScrollElem) {
84
- const { scrollLeft, clientWidth } = bodyScrollElem
85
- const startWidth = scrollLeft + leftFixedWidth
86
- const endWidth = scrollLeft + clientWidth - rightFixedWidth
87
- let toVisibleIndex = -1
88
- let cWidth = 0
89
- let visibleSize = 0
90
- for (let colIndex = 0, colLen = visibleColumn.length; colIndex < colLen; colIndex++) {
91
- cWidth += visibleColumn[colIndex].renderWidth
92
- if (toVisibleIndex === -1 && startWidth < cWidth) {
93
- toVisibleIndex = colIndex
88
+ const clientWidth = bodyScrollElem.clientWidth
89
+ let scrollLeft = bodyScrollElem.scrollLeft
90
+ if (isScrollXBig) {
91
+ scrollLeft = Math.ceil((scrollXWidth - clientWidth) * Math.min(1, (scrollLeft / (maxXWidth - clientWidth))))
92
+ }
93
+ const startLeft = scrollLeft + leftFixedWidth
94
+ const endLeft = scrollLeft + clientWidth - rightFixedWidth
95
+ let leftIndex = 0
96
+ let rightIndex = visibleColumn.length
97
+ while (leftIndex < rightIndex) {
98
+ const cIndex = Math.floor((leftIndex + rightIndex) / 2)
99
+ const column = visibleColumn[cIndex]
100
+ const colid = column.id
101
+ const colRest = fullColumnIdData[colid] || {}
102
+ if (colRest.oLeft <= startLeft) {
103
+ leftIndex = cIndex + 1
104
+ } else {
105
+ rightIndex = cIndex
94
106
  }
95
- if (toVisibleIndex >= 0) {
96
- visibleSize++
97
- if (cWidth > endWidth) {
98
- break
99
- }
107
+ }
108
+ let visibleSize = 0
109
+ const toVisibleIndex = Math.max(0, leftIndex < visibleColumn.length ? leftIndex - 2 : 0)
110
+ for (let cIndex = toVisibleIndex, cLen = visibleColumn.length; cIndex < cLen; cIndex++) {
111
+ const column = visibleColumn[cIndex]
112
+ const colid = column.id
113
+ const colRest = fullColumnIdData[colid] || {}
114
+ visibleSize++
115
+ if (colRest.oLeft > endLeft || visibleSize >= 60) {
116
+ break
100
117
  }
101
118
  }
102
119
  return { toVisibleIndex: Math.max(0, toVisibleIndex), visibleSize: Math.max(1, visibleSize) }
@@ -425,8 +442,8 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
425
442
  const internalData = $xeTable as unknown as TableInternalData
426
443
 
427
444
  const { border, showHeaderOverflow: allColumnHeaderOverflow, showFooterOverflow: allColumnFooterOverflow, mouseConfig, spanMethod, footerSpanMethod } = props
428
- const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, overflowX, scrollbarWidth, overflowY, scrollbarHeight, columnStore, editStore, isAllOverflow, expandColumn } = reactData
429
- const { visibleColumn, fullColumnIdData, tableHeight, tableWidth, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData
445
+ const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, overflowX, scrollbarWidth, overflowY, scrollbarHeight, scrollXWidth, columnStore, editStore, isAllOverflow, expandColumn } = reactData
446
+ const { visibleColumn, fullColumnIdData, tableHeight, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData
430
447
  const el = $xeTable.$refs.refElem as HTMLDivElement
431
448
  if (!el) {
432
449
  return
@@ -466,9 +483,10 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
466
483
  bodyHeight = Math.max(bodyMinHeight, bodyHeight)
467
484
  }
468
485
 
486
+ const scrollbarXToTop = $xeTable.$refs.computeScrollbarXToTop
487
+
469
488
  const xLeftCornerEl = $xeTable.$refs.refScrollXLeftCornerElem as HTMLDivElement
470
489
  const xRightCornerEl = $xeTable.$refs.refScrollXRightCornerElem as HTMLDivElement
471
- const scrollbarXToTop = $xeTable.computeScrollbarXToTop
472
490
  const scrollXVirtualEl = $xeTable.$refs.refScrollXVirtualElem as HTMLDivElement
473
491
  if (scrollXVirtualEl) {
474
492
  scrollXVirtualEl.style.height = `${osbHeight}px`
@@ -563,7 +581,7 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
563
581
  if (fixedType) {
564
582
  if (isGroup) {
565
583
  if (wrapperElem) {
566
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
584
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
567
585
  }
568
586
  } else {
569
587
  if (isOptimizeMode) {
@@ -572,7 +590,7 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
572
590
  }
573
591
  } else {
574
592
  if (wrapperElem) {
575
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
593
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
576
594
  }
577
595
  }
578
596
  }
@@ -586,11 +604,6 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
586
604
  tableElem.style.width = tWidth ? `${tWidth}px` : ''
587
605
  }
588
606
 
589
- const repairElem = getRefElem(elemStore[`${name}-${layout}-repair`])
590
- if (repairElem) {
591
- repairElem.style.width = `${tableWidth}px`
592
- }
593
-
594
607
  const listElem = getRefElem(elemStore[`${name}-${layout}-list`])
595
608
  if (isGroup && listElem) {
596
609
  XEUtils.arrayEach(listElem.querySelectorAll('.col--group'), (thElem: any) => {
@@ -661,7 +674,7 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
661
674
  }
662
675
  } else {
663
676
  if (wrapperElem) {
664
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
677
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
665
678
  }
666
679
  }
667
680
  }
@@ -703,7 +716,7 @@ function updateStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
703
716
  }
704
717
  } else {
705
718
  if (wrapperElem) {
706
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
719
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
707
720
  }
708
721
  }
709
722
  }
@@ -1033,46 +1046,52 @@ function computeRowHeight ($xeTable: VxeTableConstructor) {
1033
1046
  return Math.max(18, rowHeight)
1034
1047
  }
1035
1048
 
1036
- function handleVirtualYVisible ($xeTable: VxeTableConstructor, currScrollTop?: number) {
1049
+ function handleVirtualYVisible ($xeTable: VxeTableConstructor) {
1037
1050
  const reactData = $xeTable as unknown as TableReactData
1038
1051
  const internalData = $xeTable as unknown as TableInternalData
1039
1052
 
1040
- const { isAllOverflow, expandColumn, rowExpandedMaps } = reactData
1053
+ const { isAllOverflow, expandColumn, isScrollYBig, scrollYHeight } = reactData
1041
1054
  const { elemStore, isResizeCellHeight, afterFullData, fullAllDataRowIdData } = internalData
1042
- const expandOpts = $xeTable.computeExpandOpts
1043
1055
  const rowOpts = $xeTable.computeRowOpts
1044
1056
  const cellOpts = $xeTable.computeCellOpts
1045
1057
  const defaultRowHeight = $xeTable.computeDefaultRowHeight
1046
1058
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
1047
1059
  if (bodyScrollElem) {
1048
1060
  const clientHeight = bodyScrollElem.clientHeight
1049
- const scrollTop = XEUtils.isNumber(currScrollTop) ? currScrollTop : bodyScrollElem.scrollTop
1050
- const endHeight = scrollTop + clientHeight
1061
+ let scrollTop = bodyScrollElem.scrollTop
1062
+ if (isScrollYBig) {
1063
+ scrollTop = Math.ceil((scrollYHeight - clientHeight) * Math.min(1, (scrollTop / (maxYHeight - clientHeight))))
1064
+ }
1065
+ const startTop = scrollTop
1066
+ const endTop = scrollTop + clientHeight
1051
1067
  let toVisibleIndex = -1
1052
- let offsetTop = 0
1053
1068
  let visibleSize = 0
1054
1069
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height
1055
1070
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
1056
- toVisibleIndex = Math.floor(scrollTop / defaultRowHeight)
1071
+ toVisibleIndex = Math.floor(startTop / defaultRowHeight) - 1
1057
1072
  visibleSize = Math.ceil(clientHeight / defaultRowHeight) + 1
1058
1073
  } else {
1059
- for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
1074
+ let leftIndex = 0
1075
+ let rightIndex = afterFullData.length
1076
+ while (leftIndex < rightIndex) {
1077
+ const rIndex = Math.floor((leftIndex + rightIndex) / 2)
1060
1078
  const row = afterFullData[rIndex]
1061
1079
  const rowid = getRowid($xeTable, row)
1062
1080
  const rowRest = fullAllDataRowIdData[rowid] || {}
1063
- offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
1064
- if (toVisibleIndex === -1 && scrollTop < offsetTop) {
1065
- toVisibleIndex = rIndex
1066
- }
1067
- if (toVisibleIndex >= 0) {
1068
- visibleSize++
1069
- if (offsetTop > endHeight) {
1070
- break
1071
- }
1081
+ if (rowRest.oTop <= startTop) {
1082
+ leftIndex = rIndex + 1
1083
+ } else {
1084
+ rightIndex = rIndex
1072
1085
  }
1073
- // 是否展开行
1074
- if (expandColumn && rowExpandedMaps[rowid]) {
1075
- offsetTop += rowRest.expandHeight || expandOpts.height || 0
1086
+ }
1087
+ toVisibleIndex = Math.max(0, leftIndex < afterFullData.length ? leftIndex - 2 : 0)
1088
+ for (let rIndex = toVisibleIndex, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
1089
+ const row = afterFullData[rIndex]
1090
+ const rowid = getRowid($xeTable, row)
1091
+ const rowRest = fullAllDataRowIdData[rowid] || {}
1092
+ visibleSize++
1093
+ if (rowRest.oTop > endTop || visibleSize >= 100) {
1094
+ break
1076
1095
  }
1077
1096
  }
1078
1097
  }
@@ -1232,7 +1251,7 @@ function autoCellWidth ($xeTable: VxeTableConstructor & VxeTablePrivateMethods)
1232
1251
  if (!xHandleEl) {
1233
1252
  return
1234
1253
  }
1235
- let tableWidth = 0
1254
+ let tWidth = 0
1236
1255
  const minCellWidth = 40 // 列宽最少限制 40px
1237
1256
  const bodyWidth = bodyElem.clientWidth
1238
1257
  let remainWidth = bodyWidth
@@ -1243,51 +1262,51 @@ function autoCellWidth ($xeTable: VxeTableConstructor & VxeTablePrivateMethods)
1243
1262
  // 最小宽
1244
1263
  pxMinList.forEach((column) => {
1245
1264
  const minWidth = XEUtils.toInteger(column.minWidth)
1246
- tableWidth += minWidth
1265
+ tWidth += minWidth
1247
1266
  column.renderWidth = minWidth
1248
1267
  })
1249
1268
  // 最小自适应
1250
1269
  autoMinList.forEach((column) => {
1251
1270
  const scaleWidth = Math.max(60, XEUtils.toInteger(column.renderAutoWidth))
1252
- tableWidth += scaleWidth
1271
+ tWidth += scaleWidth
1253
1272
  column.renderWidth = scaleWidth
1254
1273
  })
1255
1274
  // 最小百分比
1256
1275
  scaleMinList.forEach((column) => {
1257
1276
  const scaleWidth = Math.floor(XEUtils.toInteger(column.minWidth) * meanWidth)
1258
- tableWidth += scaleWidth
1277
+ tWidth += scaleWidth
1259
1278
  column.renderWidth = scaleWidth
1260
1279
  })
1261
1280
  // 固定百分比
1262
1281
  scaleList.forEach((column) => {
1263
1282
  const scaleWidth = Math.floor(XEUtils.toInteger(column.width) * meanWidth)
1264
- tableWidth += scaleWidth
1283
+ tWidth += scaleWidth
1265
1284
  column.renderWidth = scaleWidth
1266
1285
  })
1267
1286
  // 固定宽
1268
1287
  pxList.forEach((column) => {
1269
1288
  const width = XEUtils.toInteger(column.width)
1270
- tableWidth += width
1289
+ tWidth += width
1271
1290
  column.renderWidth = width
1272
1291
  })
1273
1292
  // 自适应宽
1274
1293
  autoList.forEach((column) => {
1275
1294
  const width = Math.max(60, XEUtils.toInteger(column.renderAutoWidth))
1276
- tableWidth += width
1295
+ tWidth += width
1277
1296
  column.renderWidth = width
1278
1297
  })
1279
1298
  // 调整了列宽
1280
1299
  resizeList.forEach((column) => {
1281
1300
  const width = XEUtils.toInteger(column.resizeWidth)
1282
- tableWidth += width
1301
+ tWidth += width
1283
1302
  column.renderWidth = width
1284
1303
  })
1285
- remainWidth -= tableWidth
1304
+ remainWidth -= tWidth
1286
1305
  meanWidth = remainWidth > 0 ? Math.floor(remainWidth / (scaleMinList.length + pxMinList.length + autoMinList.length + remainList.length)) : 0
1287
1306
  if (fit) {
1288
1307
  if (remainWidth > 0) {
1289
1308
  scaleMinList.concat(pxMinList).concat(autoMinList).forEach((column) => {
1290
- tableWidth += meanWidth
1309
+ tWidth += meanWidth
1291
1310
  column.renderWidth += meanWidth
1292
1311
  })
1293
1312
  }
@@ -1298,7 +1317,7 @@ function autoCellWidth ($xeTable: VxeTableConstructor & VxeTablePrivateMethods)
1298
1317
  remainList.forEach((column) => {
1299
1318
  const width = Math.max(meanWidth, minCellWidth)
1300
1319
  column.renderWidth = width
1301
- tableWidth += width
1320
+ tWidth += width
1302
1321
  })
1303
1322
  if (fit) {
1304
1323
  /**
@@ -1308,13 +1327,13 @@ function autoCellWidth ($xeTable: VxeTableConstructor & VxeTablePrivateMethods)
1308
1327
  const dynamicList = scaleList.concat(scaleMinList).concat(pxMinList).concat(autoMinList).concat(remainList)
1309
1328
  let dynamicSize = dynamicList.length - 1
1310
1329
  if (dynamicSize > 0) {
1311
- let i = bodyWidth - tableWidth
1330
+ let i = bodyWidth - tWidth
1312
1331
  if (i > 0) {
1313
1332
  while (i > 0 && dynamicSize >= 0) {
1314
1333
  i--
1315
1334
  dynamicList[dynamicSize--].renderWidth++
1316
1335
  }
1317
- tableWidth = bodyWidth
1336
+ tWidth = bodyWidth
1318
1337
  }
1319
1338
  }
1320
1339
  }
@@ -1322,18 +1341,19 @@ function autoCellWidth ($xeTable: VxeTableConstructor & VxeTablePrivateMethods)
1322
1341
  const overflowY = yHandleEl.scrollHeight > yHandleEl.clientHeight
1323
1342
  reactData.scrollbarWidth = Math.max(scrollbarOpts.width || 0, yHandleEl.offsetWidth - yHandleEl.clientWidth)
1324
1343
  reactData.overflowY = overflowY
1325
- internalData.tableWidth = tableWidth
1344
+ reactData.scrollXWidth = tWidth
1326
1345
  internalData.tableHeight = tableHeight
1327
1346
 
1328
1347
  const headerTableElem = getRefElem(elemStore['main-header-table'])
1329
1348
  const footerTableElem = getRefElem(elemStore['main-footer-table'])
1330
1349
  const headerHeight = headerTableElem ? headerTableElem.clientHeight : 0
1331
- const overflowX = tableWidth > bodyWidth
1350
+ const overflowX = tWidth > bodyWidth
1332
1351
  const footerHeight = footerTableElem ? footerTableElem.clientHeight : 0
1333
1352
  reactData.scrollbarHeight = Math.max(scrollbarOpts.height || 0, xHandleEl.offsetHeight - xHandleEl.clientHeight)
1334
1353
  internalData.headerHeight = headerHeight
1335
1354
  internalData.footerHeight = footerHeight
1336
1355
  reactData.overflowX = overflowX
1356
+ updateColumnOffsetLeft($xeTable)
1337
1357
  updateHeight($xeTable)
1338
1358
  reactData.parentHeight = Math.max(internalData.headerHeight + footerHeight + 20, $xeTable.getParentHeight())
1339
1359
  if (overflowX) {
@@ -1521,8 +1541,8 @@ function showDropTip ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, ev
1521
1541
  const wrapperRect = el.getBoundingClientRect()
1522
1542
  const osbWidth = overflowY ? scrollbarWidth : 0
1523
1543
  const osbHeight = overflowX ? scrollbarHeight : 0
1524
- const tableWidth = el.clientWidth
1525
- const tableHeight = el.clientHeight
1544
+ const tableWrapperWidth = el.clientWidth
1545
+ const tableWrapperHeight = el.clientHeight
1526
1546
  if (trEl) {
1527
1547
  const rdLineEl = $xeTable.$refs.refDragRowLineElem as HTMLElement
1528
1548
  if (rdLineEl) {
@@ -1531,14 +1551,14 @@ function showDropTip ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, ev
1531
1551
  const trRect = trEl.getBoundingClientRect()
1532
1552
  let trHeight = trEl.clientHeight
1533
1553
  const offsetTop = Math.max(1, trRect.y - wrapperRect.y)
1534
- if (offsetTop + trHeight > tableHeight - osbHeight) {
1535
- trHeight = tableHeight - offsetTop - osbHeight
1554
+ if (offsetTop + trHeight > tableWrapperHeight - osbHeight) {
1555
+ trHeight = tableWrapperHeight - offsetTop - osbHeight
1536
1556
  }
1537
1557
  rdLineEl.style.display = 'block'
1538
1558
  rdLineEl.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`
1539
1559
  rdLineEl.style.top = `${offsetTop}px`
1540
1560
  rdLineEl.style.height = `${trHeight}px`
1541
- rdLineEl.style.width = `${tableWidth - osbWidth}px`
1561
+ rdLineEl.style.width = `${tableWrapperWidth - osbWidth}px`
1542
1562
  rdLineEl.setAttribute('drag-pos', dragPos)
1543
1563
  rdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
1544
1564
  } else {
@@ -1563,7 +1583,7 @@ function showDropTip ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, ev
1563
1583
  thWidth -= startX - offsetLeft
1564
1584
  offsetLeft = startX
1565
1585
  }
1566
- const endX = tableWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth)
1586
+ const endX = tableWrapperWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth)
1567
1587
  if (offsetLeft + thWidth > endX) {
1568
1588
  thWidth = endX - offsetLeft
1569
1589
  }
@@ -1574,7 +1594,7 @@ function showDropTip ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, ev
1574
1594
  if (prevDragToChild) {
1575
1595
  cdLineEl.style.height = `${thRect.height}px`
1576
1596
  } else {
1577
- cdLineEl.style.height = `${tableHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`
1597
+ cdLineEl.style.height = `${tableWrapperHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`
1578
1598
  }
1579
1599
  cdLineEl.setAttribute('drag-pos', dragPos)
1580
1600
  cdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
@@ -1655,6 +1675,21 @@ function handleScrollToRowColumn ($xeTable: VxeTableConstructor & VxeTablePrivat
1655
1675
  return $xeTable.$nextTick()
1656
1676
  }
1657
1677
 
1678
+ const handleRowExpandReserve = ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, row: any, expanded: boolean) => {
1679
+ const internalData = $xeTable as unknown as TableInternalData
1680
+
1681
+ const { rowExpandedReserveRowMap } = internalData
1682
+ const expandOpts = $xeTable.computeExpandOpts
1683
+ if (expandOpts.reserve) {
1684
+ const rowid = getRowid($xeTable, row)
1685
+ if (expanded) {
1686
+ rowExpandedReserveRowMap[rowid] = row
1687
+ } else if (rowExpandedReserveRowMap[rowid]) {
1688
+ delete rowExpandedReserveRowMap[rowid]
1689
+ }
1690
+ }
1691
+ }
1692
+
1658
1693
  // 计算可视渲染相关数据
1659
1694
  function computeScrollLoad ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
1660
1695
  const reactData = $xeTable as unknown as TableReactData
@@ -1725,14 +1760,19 @@ function handleRecalculateLayout ($xeTable: VxeTableConstructor & VxeTablePrivat
1725
1760
  calcCellWidth($xeTable)
1726
1761
  autoCellWidth($xeTable)
1727
1762
  updateStyle($xeTable)
1763
+ if (reFull) {
1764
+ updateRowOffsetTop($xeTable)
1765
+ }
1728
1766
  updateRowExpandStyle($xeTable)
1729
1767
  return computeScrollLoad($xeTable).then(() => {
1730
1768
  if (reFull === true) {
1731
1769
  // 初始化时需要在列计算之后再执行优化运算,达到最优显示效果
1732
- calcCellHeight($xeTable)
1733
1770
  calcCellWidth($xeTable)
1734
1771
  autoCellWidth($xeTable)
1735
1772
  updateStyle($xeTable)
1773
+ if (reFull) {
1774
+ updateRowOffsetTop($xeTable)
1775
+ }
1736
1776
  updateRowExpandStyle($xeTable)
1737
1777
  return computeScrollLoad($xeTable)
1738
1778
  }
@@ -1770,16 +1810,16 @@ function loadScrollXData ($xeTable: VxeTableConstructor & VxeTablePrivateMethods
1770
1810
  const reactData = $xeTable as unknown as TableReactData
1771
1811
  const internalData = $xeTable as unknown as TableInternalData
1772
1812
 
1773
- const { mergeList, mergeFooterList } = reactData
1813
+ const { mergeList, mergeFooterList, isScrollXBig } = reactData
1774
1814
  const { scrollXStore } = internalData
1775
1815
  const { preloadSize, startIndex, endIndex, offsetSize } = scrollXStore
1776
1816
  const { toVisibleIndex, visibleSize } = handleVirtualXVisible($xeTable)
1777
1817
  const offsetItem = {
1778
- startIndex: Math.max(0, toVisibleIndex - 1 - offsetSize - preloadSize),
1779
- endIndex: toVisibleIndex + visibleSize + offsetSize + preloadSize
1818
+ startIndex: Math.max(0, isScrollXBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
1819
+ endIndex: isScrollXBig ? toVisibleIndex + visibleSize : toVisibleIndex + visibleSize + offsetSize + preloadSize
1780
1820
  }
1781
- scrollXStore.visibleStartIndex = toVisibleIndex
1782
- scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize
1821
+ scrollXStore.visibleStartIndex = toVisibleIndex - 1
1822
+ scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize + 1
1783
1823
  calculateMergerOffsetIndex(mergeList.concat(mergeFooterList), offsetItem, 'col')
1784
1824
  const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem
1785
1825
  if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
@@ -1990,21 +2030,21 @@ function handleColumn ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, c
1990
2030
  /**
1991
2031
  * 纵向 Y 可视渲染处理
1992
2032
  */
1993
- function loadScrollYData ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, scrollTop?: number) {
2033
+ function loadScrollYData ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
1994
2034
  const reactData = $xeTable as unknown as TableReactData
1995
2035
  const internalData = $xeTable as unknown as TableInternalData
1996
2036
 
1997
- const { mergeList, isAllOverflow } = reactData
2037
+ const { mergeList, isAllOverflow, isScrollYBig } = reactData
1998
2038
  const { scrollYStore } = internalData
1999
2039
  const { preloadSize, startIndex, endIndex, offsetSize } = scrollYStore
2000
2040
  const autoOffsetYSize = isAllOverflow ? offsetSize : offsetSize + 1
2001
- const { toVisibleIndex, visibleSize } = handleVirtualYVisible($xeTable, scrollTop)
2041
+ const { toVisibleIndex, visibleSize } = handleVirtualYVisible($xeTable)
2002
2042
  const offsetItem = {
2003
- startIndex: Math.max(0, toVisibleIndex - 1 - offsetSize - preloadSize),
2004
- endIndex: toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize
2043
+ startIndex: Math.max(0, isScrollYBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
2044
+ endIndex: isScrollYBig ? (toVisibleIndex + visibleSize) : (toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize)
2005
2045
  }
2006
- scrollYStore.visibleStartIndex = toVisibleIndex
2007
- scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize
2046
+ scrollYStore.visibleStartIndex = toVisibleIndex - 1
2047
+ scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize + 1
2008
2048
  calculateMergerOffsetIndex(mergeList, offsetItem, 'row')
2009
2049
  const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem
2010
2050
  if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
@@ -2203,6 +2243,44 @@ function handleUpdateRowResize ($xeTable: VxeTableConstructor & VxeTablePrivateM
2203
2243
  })
2204
2244
  }
2205
2245
 
2246
+ function updateColumnOffsetLeft ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
2247
+ const internalData = $xeTable as unknown as TableInternalData
2248
+
2249
+ const { visibleColumn, fullColumnIdData } = internalData
2250
+ let offsetLeft = 0
2251
+ for (let cIndex = 0, rLen = visibleColumn.length; cIndex < rLen; cIndex++) {
2252
+ const column = visibleColumn[cIndex]
2253
+ const colid = column.id
2254
+ const colRest = fullColumnIdData[colid]
2255
+ colRest.oLeft = offsetLeft
2256
+ offsetLeft += column.renderWidth
2257
+ }
2258
+ }
2259
+
2260
+ function updateRowOffsetTop ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
2261
+ const reactData = $xeTable as unknown as TableReactData
2262
+ const internalData = $xeTable as unknown as TableInternalData
2263
+
2264
+ const { expandColumn, rowExpandedMaps } = reactData
2265
+ const { afterFullData, fullAllDataRowIdData } = internalData
2266
+ const expandOpts = $xeTable.computeExpandOpts
2267
+ const rowOpts = $xeTable.computeRowOpts
2268
+ const cellOpts = $xeTable.computeCellOpts
2269
+ const defaultRowHeight = $xeTable.computeDefaultRowHeight
2270
+ let offsetTop = 0
2271
+ for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
2272
+ const row = afterFullData[rIndex]
2273
+ const rowid = getRowid($xeTable, row)
2274
+ const rowRest = fullAllDataRowIdData[rowid] || {}
2275
+ rowRest.oTop = offsetTop
2276
+ offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
2277
+ // 是否展开行
2278
+ if (expandColumn && rowExpandedMaps[rowid]) {
2279
+ offsetTop += rowRest.expandHeight || expandOpts.height || 0
2280
+ }
2281
+ }
2282
+ }
2283
+
2206
2284
  function updateRowExpandStyle ($xeTable: VxeTableConstructor & VxeTablePrivateMethods) {
2207
2285
  const reactData = $xeTable as unknown as TableReactData
2208
2286
  const internalData = $xeTable as unknown as TableInternalData
@@ -4163,7 +4241,7 @@ const Methods = {
4163
4241
  resizeBarElem.style.height = `${scrollbarXToTop ? tableHeight - osbHeight : tableHeight}px`
4164
4242
  if (resizableOpts.showDragTip && resizeTipElem) {
4165
4243
  resizeTipElem.textContent = getI18n('vxe.table.resizeColTip', [resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)])
4166
- const tableWidth = tableEl.clientWidth
4244
+ const tableWrapperWidth = tableEl.clientWidth
4167
4245
  const wrapperRect = wrapperElem.getBoundingClientRect()
4168
4246
  const resizeBarWidth = resizeBarElem.clientWidth
4169
4247
  const resizeTipWidth = resizeTipElem.clientWidth
@@ -4171,8 +4249,8 @@ const Methods = {
4171
4249
  let resizeTipLeft = -resizeTipWidth
4172
4250
  if (resizeBarLeft < resizeTipWidth + resizeBarWidth) {
4173
4251
  resizeTipLeft = 0
4174
- } else if (resizeBarLeft > tableWidth) {
4175
- resizeTipLeft += tableWidth - resizeBarLeft
4252
+ } else if (resizeBarLeft > tableWrapperWidth) {
4253
+ resizeTipLeft += tableWrapperWidth - resizeBarLeft
4176
4254
  }
4177
4255
  resizeTipElem.style.left = `${resizeTipLeft}px`
4178
4256
  resizeTipElem.style.top = `${Math.min(tableHeight - resizeTipHeight, Math.max(0, evnt.clientY - wrapperRect.y - resizeTipHeight / 2))}px`
@@ -4316,7 +4394,7 @@ const Methods = {
4316
4394
  const updateEvent = (evnt: MouseEvent) => {
4317
4395
  evnt.stopPropagation()
4318
4396
  evnt.preventDefault()
4319
- const tableWidth = tableEl.clientWidth - osbWidth
4397
+ const rtWidth = tableEl.clientWidth - osbWidth
4320
4398
  const tableHeight = tableEl.clientHeight - osbHeight
4321
4399
  let dragTop = evnt.clientY - tableRect.y - targetOffsetY
4322
4400
  if (dragTop < minTop) {
@@ -4326,15 +4404,15 @@ const Methods = {
4326
4404
  }
4327
4405
  resizeBarElem.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`
4328
4406
  resizeBarElem.style.top = `${dragTop}px`
4329
- resizeBarElem.style.width = `${tableWidth}px`
4407
+ resizeBarElem.style.width = `${rtWidth}px`
4330
4408
  if (resizableOpts.showDragTip && resizeTipElem) {
4331
4409
  resizeTipElem.textContent = getI18n('vxe.table.resizeRowTip', [resizeHeight])
4332
4410
  const resizeTipWidth = resizeTipElem.clientWidth
4333
4411
  const resizeTipHeight = resizeTipElem.clientHeight
4334
4412
  let resizeBarLeft = Math.max(2, evnt.clientX - tableRect.x)
4335
4413
  let resizeBarTop = 0
4336
- if (resizeBarLeft + resizeTipWidth >= tableWidth - 2) {
4337
- resizeBarLeft = tableWidth - resizeTipWidth - 2
4414
+ if (resizeBarLeft + resizeTipWidth >= rtWidth - 2) {
4415
+ resizeBarLeft = rtWidth - resizeTipWidth - 2
4338
4416
  }
4339
4417
  if (dragTop + resizeTipHeight >= tableHeight) {
4340
4418
  resizeBarTop = tableHeight - (dragTop + resizeTipHeight)
@@ -4367,6 +4445,7 @@ const Methods = {
4367
4445
  } else {
4368
4446
  rowRest.resizeHeight = resizeHeight
4369
4447
  handleUpdateRowResize($xeTable, evnt, resizeParams)
4448
+ updateRowOffsetTop($xeTable)
4370
4449
  }
4371
4450
  }
4372
4451
  removeClass(tableEl, 'row-drag--resize')
@@ -7043,21 +7122,21 @@ const Methods = {
7043
7122
  const scrollTargetEl = xHandleEl || tableBodyElem
7044
7123
  if (scrollTargetEl) {
7045
7124
  const wrapperRect = el.getBoundingClientRect()
7046
- const tableWidth = el.clientWidth
7125
+ const tableWrapperWidth = el.clientWidth
7047
7126
  const leftContainerElem = $xeTable.$refs.refLeftContainer as HTMLDivElement
7048
7127
  const leftContainerWidth = leftContainerElem ? leftContainerElem.clientWidth : 0
7049
7128
  const rightContainerElem = $xeTable.$refs.refRightContainer as HTMLDivElement
7050
7129
  const rightContainerWidth = rightContainerElem ? rightContainerElem.clientWidth : 0
7051
7130
  const srartX = wrapperRect.x + leftContainerWidth
7052
- const endX = wrapperRect.x + tableWidth - rightContainerWidth
7131
+ const endX = wrapperRect.x + tableWrapperWidth - rightContainerWidth
7053
7132
  const distSize = 28
7054
7133
  const startDistSize = clientX - srartX
7055
7134
  const endDistSize = endX - clientX
7056
7135
  if (startDistSize > 0 && startDistSize <= distSize) {
7057
- const scrollRatio = Math.floor(tableWidth / (startDistSize > distSize / 2 ? 240 : 120))
7136
+ const scrollRatio = Math.floor(tableWrapperWidth / (startDistSize > distSize / 2 ? 240 : 120))
7058
7137
  scrollTargetEl.scrollLeft -= scrollRatio * (distSize - startDistSize)
7059
7138
  } else if (endDistSize > 0 && endDistSize <= distSize) {
7060
- const scrollRatio = Math.floor(tableWidth / (endDistSize > distSize / 2 ? 240 : 120))
7139
+ const scrollRatio = Math.floor(tableWrapperWidth / (endDistSize > distSize / 2 ? 240 : 120))
7061
7140
  scrollTargetEl.scrollLeft += scrollRatio * (distSize - endDistSize)
7062
7141
  }
7063
7142
  }
@@ -7558,17 +7637,17 @@ const Methods = {
7558
7637
  })
7559
7638
  }
7560
7639
  if (reserve) {
7561
- validRows.forEach((row) => this.handleRowExpandReserve(row, expanded))
7640
+ validRows.forEach((row) => handleRowExpandReserve($xeTable, row, expanded))
7562
7641
  }
7563
7642
  }
7564
7643
  this.rowExpandedMaps = rExpandedMaps
7565
7644
  return Promise.all(lazyRests)
7566
- .then(() => $xeTable.recalculate())
7645
+ .then(() => $xeTable.$nextTick())
7646
+ .then(() => $xeTable.recalculate(true))
7567
7647
  .then(() => {
7568
- if (expandColumn) {
7569
- updateRowExpandStyle($xeTable)
7570
- handleRowExpandScroll($xeTable)
7571
- }
7648
+ updateRowOffsetTop($xeTable)
7649
+ updateRowExpandStyle($xeTable)
7650
+ handleRowExpandScroll($xeTable)
7572
7651
  return $xeTable.updateCellAreas()
7573
7652
  })
7574
7653
  },
@@ -7592,36 +7671,33 @@ const Methods = {
7592
7671
  * 手动清空展开行状态,数据会恢复成未展开的状态
7593
7672
  */
7594
7673
  clearRowExpand () {
7595
- const $xeTable = this
7674
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
7675
+ const reactData = $xeTable as unknown as TableReactData
7676
+ const internalData = $xeTable as unknown as TableInternalData
7596
7677
 
7597
- const { expandOpts, tableFullData } = this
7678
+ const { tableFullData } = internalData
7679
+ const expandOpts = $xeTable.computeExpandOpts
7598
7680
  const { reserve } = expandOpts
7599
- const expList = this.getRowExpandRecords()
7600
- this.rowExpandedMaps = {}
7681
+ const expList = $xeTable.getRowExpandRecords()
7682
+ reactData.rowExpandedMaps = {}
7601
7683
  if (reserve) {
7602
- tableFullData.forEach((row: any) => this.handleRowExpandReserve(row, false))
7684
+ tableFullData.forEach((row) => handleRowExpandReserve($xeTable, row, false))
7603
7685
  }
7604
- return this.$nextTick().then(() => {
7686
+ return $xeTable.$nextTick().then(() => {
7605
7687
  if (expList.length) {
7606
- this.recalculate()
7688
+ return $xeTable.recalculate(true)
7607
7689
  }
7608
- }).then(() => $xeTable.updateCellAreas())
7690
+ }).then(() => {
7691
+ updateRowOffsetTop($xeTable)
7692
+ updateRowExpandStyle($xeTable)
7693
+ handleRowExpandScroll($xeTable)
7694
+ return $xeTable.updateCellAreas()
7695
+ })
7609
7696
  },
7610
7697
  clearRowExpandReserve () {
7611
7698
  this.rowExpandedReserveRowMap = {}
7612
7699
  return this.$nextTick()
7613
7700
  },
7614
- handleRowExpandReserve (row: any, expanded: any) {
7615
- const { rowExpandedReserveRowMap, expandOpts } = this
7616
- if (expandOpts.reserve) {
7617
- const rowid = getRowid(this, row)
7618
- if (expanded) {
7619
- rowExpandedReserveRowMap[rowid] = row
7620
- } else if (rowExpandedReserveRowMap[rowid]) {
7621
- delete rowExpandedReserveRowMap[rowid]
7622
- }
7623
- }
7624
- },
7625
7701
  getRowExpandRecords () {
7626
7702
  const rest: any[] = []
7627
7703
  XEUtils.each(this.rowExpandedMaps, item => {
@@ -7657,7 +7733,7 @@ const Methods = {
7657
7733
  * @param {Row} row 行对象
7658
7734
  */
7659
7735
  isTreeExpandLoaded (row: any) {
7660
- const $xeTable = this
7736
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
7661
7737
 
7662
7738
  const { fullAllDataRowIdData } = this
7663
7739
  const rowRest = fullAllDataRowIdData[getRowid($xeTable, row)]
@@ -8523,43 +8599,70 @@ const Methods = {
8523
8599
  const reactData = $xeTable as unknown as TableReactData
8524
8600
  const internalData = $xeTable as unknown as TableInternalData
8525
8601
 
8526
- const { isGroup, scrollXLoad } = reactData
8527
- const { visibleColumn, scrollXStore, elemStore, tableWidth } = internalData
8528
- const tableHeader = $xeTable.$refs.refTableHeader
8602
+ const { isGroup, scrollXLoad, overflowX, scrollXWidth } = reactData
8603
+ const { visibleColumn, scrollXStore, elemStore, fullColumnIdData } = internalData
8529
8604
  const tableBody = $xeTable.$refs.refTableBody
8530
- const tableFooter = $xeTable.$refs.refTableFooter
8531
8605
  const tableBodyElem = tableBody ? (tableBody as any).$el as HTMLDivElement : null
8532
8606
  if (tableBodyElem) {
8533
- const tableHeaderElem = tableHeader ? (tableHeader as any).$el as HTMLDivElement : null
8534
- const tableFooterElem = tableFooter ? (tableFooter as any).$el as HTMLDivElement : null
8535
- const headerElem = tableHeaderElem ? tableHeaderElem.querySelector('.vxe-table--header') as HTMLTableElement : null
8536
- const bodyElem = tableBodyElem.querySelector('.vxe-table--body') as HTMLTableElement
8537
- const footerElem = tableFooterElem ? tableFooterElem.querySelector('.vxe-table--footer') as HTMLTableElement : null
8538
- const leftSpaceWidth = visibleColumn.slice(0, scrollXStore.startIndex).reduce((previous, column) => previous + column.renderWidth, 0)
8607
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
8608
+ const bodyTableElem = getRefElem(elemStore['main-body-table'])
8609
+ const headerTableElem = getRefElem(elemStore['main-header-table'])
8610
+ const footerTableElem = getRefElem(elemStore['main-footer-table'])
8611
+
8612
+ let xSpaceLeft = 0
8613
+ const firstColumn = visibleColumn[scrollXStore.startIndex]
8614
+ if (firstColumn) {
8615
+ const colRest = fullColumnIdData[firstColumn.id] || {}
8616
+ xSpaceLeft = colRest.oLeft
8617
+ }
8618
+
8619
+ let clientWidth = 0
8620
+ if (bodyScrollElem) {
8621
+ clientWidth = bodyScrollElem.clientWidth
8622
+ }
8623
+ // 虚拟渲染
8624
+ let isScrollXBig = false
8625
+ let ySpaceWidth = scrollXWidth
8626
+ if (scrollXWidth > maxXWidth) {
8627
+ // 触右
8628
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
8629
+ xSpaceLeft = maxXWidth - bodyTableElem.clientWidth
8630
+ } else {
8631
+ xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth))
8632
+ }
8633
+ ySpaceWidth = maxXWidth
8634
+ isScrollXBig = true
8635
+ }
8636
+
8539
8637
  let marginLeft = ''
8540
- if (scrollXLoad) {
8541
- marginLeft = `${leftSpaceWidth}px`
8638
+ if (scrollXLoad && overflowX) {
8639
+ marginLeft = `${xSpaceLeft}px`
8542
8640
  }
8543
- if (headerElem) {
8544
- headerElem.style.marginLeft = isGroup ? '' : marginLeft
8641
+ if (headerTableElem) {
8642
+ headerTableElem.style.marginLeft = isGroup ? '' : marginLeft
8545
8643
  }
8546
- bodyElem.style.marginLeft = marginLeft
8547
- if (footerElem) {
8548
- footerElem.style.marginLeft = marginLeft
8644
+ if (bodyTableElem) {
8645
+ bodyTableElem.style.marginLeft = marginLeft
8549
8646
  }
8647
+ if (footerTableElem) {
8648
+ footerTableElem.style.marginLeft = marginLeft
8649
+ }
8650
+
8651
+ reactData.isScrollXBig = isScrollXBig
8652
+
8550
8653
  const containerList = ['main']
8551
8654
  containerList.forEach(name => {
8552
8655
  const layoutList = ['header', 'body', 'footer']
8553
8656
  layoutList.forEach(layout => {
8554
8657
  const xSpaceElem = getRefElem(elemStore[`${name}-${layout}-xSpace`])
8555
8658
  if (xSpaceElem) {
8556
- xSpaceElem.style.width = scrollXLoad ? `${tableWidth}px` : ''
8659
+ xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : ''
8557
8660
  }
8558
8661
  })
8559
8662
  })
8560
8663
  const scrollXSpaceEl = $xeTable.$refs.refScrollXSpaceElem as HTMLDivElement
8561
8664
  if (scrollXSpaceEl) {
8562
- scrollXSpaceEl.style.width = `${tableWidth}px`
8665
+ scrollXSpaceEl.style.width = `${ySpaceWidth}px`
8563
8666
  }
8564
8667
  $xeTable.$nextTick(() => {
8565
8668
  updateStyle($xeTable)
@@ -8589,48 +8692,64 @@ const Methods = {
8589
8692
  const rowOpts = $xeTable.computeRowOpts
8590
8693
  const cellOpts = $xeTable.computeCellOpts
8591
8694
  const defaultRowHeight = $xeTable.computeDefaultRowHeight
8695
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
8592
8696
  const bodyTableElem = getRefElem(elemStore['main-body-table'])
8593
8697
  const containerList = ['main', 'left', 'right']
8594
- let topSpaceHeight = 0
8595
- let ySpaceHeight = 0
8596
-
8698
+ let ySpaceTop = 0
8699
+ let scrollYHeight = 0
8700
+ let isScrollYBig = false
8597
8701
  if (scrollYLoad) {
8598
8702
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height
8599
8703
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
8600
- ySpaceHeight = afterFullData.length * defaultRowHeight
8601
- topSpaceHeight = Math.max(0, startIndex * defaultRowHeight)
8704
+ scrollYHeight = afterFullData.length * defaultRowHeight
8705
+ if (scrollYHeight > maxYHeight) {
8706
+ isScrollYBig = true
8707
+ }
8708
+ ySpaceTop = Math.max(0, startIndex * defaultRowHeight)
8602
8709
  } else {
8603
- for (let i = 0; i < afterFullData.length; i++) {
8604
- const row = afterFullData[i]
8605
- const rowid = getRowid($xeTable, row)
8606
- const rowRest = fullAllDataRowIdData[rowid] || {}
8607
- ySpaceHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
8608
- // 是否展开行
8609
- if (expandColumn && rowExpandedMaps[rowid]) {
8610
- ySpaceHeight += rowRest.expandHeight || expandOpts.height || 0
8611
- }
8710
+ const firstRow = afterFullData[startIndex]
8711
+ let rowid = getRowid($xeTable, firstRow)
8712
+ let rowRest = fullAllDataRowIdData[rowid] || {}
8713
+ ySpaceTop = rowRest.oTop
8714
+
8715
+ const lastRow = afterFullData[afterFullData.length - 1]
8716
+ rowid = getRowid($xeTable, lastRow)
8717
+ rowRest = fullAllDataRowIdData[rowid] || {}
8718
+ scrollYHeight = rowRest.oTop + (rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight)
8719
+ // 是否展开行
8720
+ if (expandColumn && rowExpandedMaps[rowid]) {
8721
+ scrollYHeight += rowRest.expandHeight || expandOpts.height || 0
8612
8722
  }
8613
- for (let i = 0; i < startIndex; i++) {
8614
- const row = afterFullData[i]
8615
- const rowid = getRowid($xeTable, row)
8616
- const rowRest = fullAllDataRowIdData[rowid] || {}
8617
- topSpaceHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
8618
- // 是否展开行
8619
- if (expandColumn && rowExpandedMaps[rowid]) {
8620
- topSpaceHeight += rowRest.expandHeight || expandOpts.height || 0
8621
- }
8723
+ if (scrollYHeight > maxYHeight) {
8724
+ isScrollYBig = true
8622
8725
  }
8623
8726
  }
8624
8727
  } else {
8625
8728
  if (bodyTableElem) {
8626
- ySpaceHeight = bodyTableElem.clientHeight
8729
+ scrollYHeight = bodyTableElem.clientHeight
8730
+ }
8731
+ }
8732
+ let clientHeight = 0
8733
+ if (bodyScrollElem) {
8734
+ clientHeight = bodyScrollElem.clientHeight
8735
+ }
8736
+ // 虚拟渲染
8737
+ let ySpaceHeight = scrollYHeight
8738
+ let scrollYTop = ySpaceTop
8739
+ if (isScrollYBig) {
8740
+ // 触底
8741
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
8742
+ scrollYTop = maxYHeight - bodyTableElem.clientHeight
8743
+ } else {
8744
+ scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight))
8627
8745
  }
8746
+ ySpaceHeight = maxYHeight
8628
8747
  }
8629
8748
  containerList.forEach(name => {
8630
8749
  const layoutList = ['header', 'body', 'footer']
8631
8750
  const tableElem = getRefElem(elemStore[`${name}-body-table`])
8632
8751
  if (tableElem) {
8633
- tableElem.style.marginTop = topSpaceHeight ? `${topSpaceHeight}px` : ''
8752
+ tableElem.style.marginTop = scrollYTop ? `${scrollYTop}px` : ''
8634
8753
  }
8635
8754
  layoutList.forEach(layout => {
8636
8755
  const ySpaceElem = getRefElem(elemStore[`${name}-${layout}-ySpace`])
@@ -8647,6 +8766,9 @@ const Methods = {
8647
8766
  if (rowExpandYSpaceEl) {
8648
8767
  rowExpandYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : ''
8649
8768
  }
8769
+ reactData.scrollYTop = scrollYTop
8770
+ reactData.scrollYHeight = scrollYHeight
8771
+ reactData.isScrollYBig = isScrollYBig
8650
8772
  return $xeTable.$nextTick().then(() => {
8651
8773
  updateStyle($xeTable)
8652
8774
  })