vxe-table 4.11.16 → 4.12.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.
@@ -24,6 +24,8 @@ import type { VxeGridConstructor, VxeGridPrivateMethods, VxeTableConstructor, Ta
24
24
  const { getConfig, getIcon, getI18n, renderer, formats, createEvent, globalResize, interceptor, hooks, globalEvents, GLOBAL_EVENT_KEYS, useFns, renderEmptyElement } = VxeUI
25
25
 
26
26
  const customStorageKey = 'VXE_CUSTOM_STORE'
27
+ const maxYHeight = 5e6
28
+ const maxXWidth = 5e6
27
29
 
28
30
  export default defineComponent({
29
31
  name: 'VxeTable',
@@ -939,27 +941,41 @@ export default defineComponent({
939
941
  }
940
942
 
941
943
  const handleVirtualXVisible = () => {
942
- const { elemStore, visibleColumn } = internalData
944
+ const { isScrollXBig, scrollXWidth } = reactData
945
+ const { elemStore, visibleColumn, fullColumnIdData } = internalData
943
946
  const leftFixedWidth = computeLeftFixedWidth.value
944
947
  const rightFixedWidth = computeRightFixedWidth.value
945
948
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
946
949
  if (bodyScrollElem) {
947
- const { scrollLeft, clientWidth } = bodyScrollElem
948
- const startWidth = scrollLeft + leftFixedWidth
949
- const endWidth = scrollLeft + clientWidth - rightFixedWidth
950
- let toVisibleIndex = -1
951
- let cWidth = 0
952
- let visibleSize = 0
953
- for (let colIndex = 0, colLen = visibleColumn.length; colIndex < colLen; colIndex++) {
954
- cWidth += visibleColumn[colIndex].renderWidth
955
- if (toVisibleIndex === -1 && startWidth < cWidth) {
956
- toVisibleIndex = colIndex
950
+ const clientWidth = bodyScrollElem.clientWidth
951
+ let scrollLeft = bodyScrollElem.scrollLeft
952
+ if (isScrollXBig) {
953
+ scrollLeft = Math.ceil((scrollXWidth - clientWidth) * Math.min(1, (scrollLeft / (maxXWidth - clientWidth))))
954
+ }
955
+ const startLeft = scrollLeft + leftFixedWidth
956
+ const endLeft = scrollLeft + clientWidth - rightFixedWidth
957
+ let leftIndex = 0
958
+ let rightIndex = visibleColumn.length
959
+ while (leftIndex < rightIndex) {
960
+ const cIndex = Math.floor((leftIndex + rightIndex) / 2)
961
+ const column = visibleColumn[cIndex]
962
+ const colid = column.id
963
+ const colRest = fullColumnIdData[colid] || {}
964
+ if (colRest.oLeft <= startLeft) {
965
+ leftIndex = cIndex + 1
966
+ } else {
967
+ rightIndex = cIndex
957
968
  }
958
- if (toVisibleIndex >= 0) {
959
- visibleSize++
960
- if (cWidth > endWidth) {
961
- break
962
- }
969
+ }
970
+ let visibleSize = 0
971
+ const toVisibleIndex = Math.max(0, leftIndex < visibleColumn.length ? leftIndex - 2 : 0)
972
+ for (let cIndex = toVisibleIndex, cLen = visibleColumn.length; cIndex < cLen; cIndex++) {
973
+ const column = visibleColumn[cIndex]
974
+ const colid = column.id
975
+ const colRest = fullColumnIdData[colid] || {}
976
+ visibleSize++
977
+ if (colRest.oLeft > endLeft || visibleSize >= 60) {
978
+ break
963
979
  }
964
980
  }
965
981
  return { toVisibleIndex: Math.max(0, toVisibleIndex), visibleSize: Math.max(1, visibleSize) }
@@ -1003,43 +1019,49 @@ export default defineComponent({
1003
1019
  return Math.max(18, rowHeight)
1004
1020
  }
1005
1021
 
1006
- const handleVirtualYVisible = (currScrollTop?: number) => {
1007
- const { isAllOverflow, expandColumn, rowExpandedMaps } = reactData
1022
+ const handleVirtualYVisible = () => {
1023
+ const { isAllOverflow, expandColumn, isScrollYBig, scrollYHeight } = reactData
1008
1024
  const { elemStore, isResizeCellHeight, afterFullData, fullAllDataRowIdData } = internalData
1009
- const expandOpts = computeExpandOpts.value
1010
1025
  const rowOpts = computeRowOpts.value
1011
1026
  const cellOpts = computeCellOpts.value
1012
1027
  const defaultRowHeight = computeDefaultRowHeight.value
1013
1028
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
1014
1029
  if (bodyScrollElem) {
1015
1030
  const clientHeight = bodyScrollElem.clientHeight
1016
- const scrollTop = XEUtils.isNumber(currScrollTop) ? currScrollTop : bodyScrollElem.scrollTop
1017
- const endHeight = scrollTop + clientHeight
1031
+ let scrollTop = bodyScrollElem.scrollTop
1032
+ if (isScrollYBig) {
1033
+ scrollTop = Math.ceil((scrollYHeight - clientHeight) * Math.min(1, (scrollTop / (maxYHeight - clientHeight))))
1034
+ }
1035
+ const startTop = scrollTop
1036
+ const endTop = scrollTop + clientHeight
1018
1037
  let toVisibleIndex = -1
1019
- let offsetTop = 0
1020
1038
  let visibleSize = 0
1021
1039
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height
1022
1040
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
1023
- toVisibleIndex = Math.floor(scrollTop / defaultRowHeight)
1041
+ toVisibleIndex = Math.floor(startTop / defaultRowHeight) - 1
1024
1042
  visibleSize = Math.ceil(clientHeight / defaultRowHeight) + 1
1025
1043
  } else {
1026
- for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
1044
+ let leftIndex = 0
1045
+ let rightIndex = afterFullData.length
1046
+ while (leftIndex < rightIndex) {
1047
+ const rIndex = Math.floor((leftIndex + rightIndex) / 2)
1027
1048
  const row = afterFullData[rIndex]
1028
1049
  const rowid = getRowid($xeTable, row)
1029
1050
  const rowRest = fullAllDataRowIdData[rowid] || {}
1030
- offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
1031
- if (toVisibleIndex === -1 && scrollTop < offsetTop) {
1032
- toVisibleIndex = rIndex
1033
- }
1034
- if (toVisibleIndex >= 0) {
1035
- visibleSize++
1036
- if (offsetTop > endHeight) {
1037
- break
1038
- }
1051
+ if (rowRest.oTop <= startTop) {
1052
+ leftIndex = rIndex + 1
1053
+ } else {
1054
+ rightIndex = rIndex
1039
1055
  }
1040
- // 是否展开行
1041
- if (expandColumn && rowExpandedMaps[rowid]) {
1042
- offsetTop += rowRest.expandHeight || expandOpts.height || 0
1056
+ }
1057
+ toVisibleIndex = Math.max(0, leftIndex < afterFullData.length ? leftIndex - 2 : 0)
1058
+ for (let rIndex = toVisibleIndex, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
1059
+ const row = afterFullData[rIndex]
1060
+ const rowid = getRowid($xeTable, row)
1061
+ const rowRest = fullAllDataRowIdData[rowid] || {}
1062
+ visibleSize++
1063
+ if (rowRest.oTop > endTop || visibleSize >= 100) {
1064
+ break
1043
1065
  }
1044
1066
  }
1045
1067
  }
@@ -1426,7 +1448,7 @@ export default defineComponent({
1426
1448
  if (!xHandleEl) {
1427
1449
  return
1428
1450
  }
1429
- let tableWidth = 0
1451
+ let tWidth = 0
1430
1452
  const minCellWidth = 40 // 列宽最少限制 40px
1431
1453
  const bodyWidth = bodyElem.clientWidth
1432
1454
  let remainWidth = bodyWidth
@@ -1437,51 +1459,51 @@ export default defineComponent({
1437
1459
  // 最小宽
1438
1460
  pxMinList.forEach((column) => {
1439
1461
  const minWidth = XEUtils.toInteger(column.minWidth)
1440
- tableWidth += minWidth
1462
+ tWidth += minWidth
1441
1463
  column.renderWidth = minWidth
1442
1464
  })
1443
1465
  // 最小自适应
1444
1466
  autoMinList.forEach((column) => {
1445
1467
  const caWidth = Math.max(60, XEUtils.toInteger(column.renderAutoWidth))
1446
- tableWidth += caWidth
1468
+ tWidth += caWidth
1447
1469
  column.renderWidth = caWidth
1448
1470
  })
1449
1471
  // 最小百分比
1450
1472
  scaleMinList.forEach((column) => {
1451
1473
  const smWidth = Math.floor(XEUtils.toInteger(column.minWidth) * meanWidth)
1452
- tableWidth += smWidth
1474
+ tWidth += smWidth
1453
1475
  column.renderWidth = smWidth
1454
1476
  })
1455
1477
  // 固定百分比
1456
1478
  scaleList.forEach((column) => {
1457
1479
  const sfWidth = Math.floor(XEUtils.toInteger(column.width) * meanWidth)
1458
- tableWidth += sfWidth
1480
+ tWidth += sfWidth
1459
1481
  column.renderWidth = sfWidth
1460
1482
  })
1461
1483
  // 固定宽
1462
1484
  pxList.forEach((column) => {
1463
1485
  const pWidth = XEUtils.toInteger(column.width)
1464
- tableWidth += pWidth
1486
+ tWidth += pWidth
1465
1487
  column.renderWidth = pWidth
1466
1488
  })
1467
1489
  // 自适应宽
1468
1490
  autoList.forEach((column) => {
1469
1491
  const aWidth = Math.max(60, XEUtils.toInteger(column.renderAutoWidth))
1470
- tableWidth += aWidth
1492
+ tWidth += aWidth
1471
1493
  column.renderWidth = aWidth
1472
1494
  })
1473
1495
  // 调整了列宽
1474
1496
  resizeList.forEach((column) => {
1475
1497
  const reWidth = XEUtils.toInteger(column.resizeWidth)
1476
- tableWidth += reWidth
1498
+ tWidth += reWidth
1477
1499
  column.renderWidth = reWidth
1478
1500
  })
1479
- remainWidth -= tableWidth
1501
+ remainWidth -= tWidth
1480
1502
  meanWidth = remainWidth > 0 ? Math.floor(remainWidth / (scaleMinList.length + pxMinList.length + autoMinList.length + remainList.length)) : 0
1481
1503
  if (fit) {
1482
1504
  if (remainWidth > 0) {
1483
1505
  scaleMinList.concat(pxMinList).concat(autoMinList).forEach((column) => {
1484
- tableWidth += meanWidth
1506
+ tWidth += meanWidth
1485
1507
  column.renderWidth += meanWidth
1486
1508
  })
1487
1509
  }
@@ -1492,7 +1514,7 @@ export default defineComponent({
1492
1514
  remainList.forEach((column) => {
1493
1515
  const width = Math.max(meanWidth, minCellWidth)
1494
1516
  column.renderWidth = width
1495
- tableWidth += width
1517
+ tWidth += width
1496
1518
  })
1497
1519
  if (fit) {
1498
1520
  /**
@@ -1502,13 +1524,13 @@ export default defineComponent({
1502
1524
  const dynamicList = scaleList.concat(scaleMinList).concat(pxMinList).concat(autoMinList).concat(remainList)
1503
1525
  let dynamicSize = dynamicList.length - 1
1504
1526
  if (dynamicSize > 0) {
1505
- let i = bodyWidth - tableWidth
1527
+ let i = bodyWidth - tWidth
1506
1528
  if (i > 0) {
1507
1529
  while (i > 0 && dynamicSize >= 0) {
1508
1530
  i--
1509
1531
  dynamicList[dynamicSize--].renderWidth++
1510
1532
  }
1511
- tableWidth = bodyWidth
1533
+ tWidth = bodyWidth
1512
1534
  }
1513
1535
  }
1514
1536
  }
@@ -1516,18 +1538,19 @@ export default defineComponent({
1516
1538
  const overflowY = yHandleEl.scrollHeight > yHandleEl.clientHeight
1517
1539
  reactData.scrollbarWidth = Math.max(scrollbarOpts.width || 0, yHandleEl.offsetWidth - yHandleEl.clientWidth)
1518
1540
  reactData.overflowY = overflowY
1519
- internalData.tableWidth = tableWidth
1541
+ reactData.scrollXWidth = tWidth
1520
1542
  internalData.tableHeight = tableHeight
1521
1543
 
1522
1544
  const headerTableElem = getRefElem(elemStore['main-header-table'])
1523
1545
  const footerTableElem = getRefElem(elemStore['main-footer-table'])
1524
1546
  const headerHeight = headerTableElem ? headerTableElem.clientHeight : 0
1525
- const overflowX = tableWidth > bodyWidth
1547
+ const overflowX = tWidth > bodyWidth
1526
1548
  const footerHeight = footerTableElem ? footerTableElem.clientHeight : 0
1527
1549
  reactData.scrollbarHeight = Math.max(scrollbarOpts.height || 0, xHandleEl.offsetHeight - xHandleEl.clientHeight)
1528
1550
  internalData.headerHeight = headerHeight
1529
1551
  internalData.footerHeight = footerHeight
1530
1552
  reactData.overflowX = overflowX
1553
+ updateColumnOffsetLeft()
1531
1554
  updateHeight()
1532
1555
  reactData.parentHeight = Math.max(internalData.headerHeight + footerHeight + 20, $xeTable.getParentHeight())
1533
1556
  if (overflowX) {
@@ -1832,8 +1855,8 @@ export default defineComponent({
1832
1855
 
1833
1856
  const updateStyle = () => {
1834
1857
  const { border, showHeaderOverflow: allColumnHeaderOverflow, showFooterOverflow: allColumnFooterOverflow, mouseConfig, spanMethod, footerSpanMethod } = props
1835
- const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, overflowX, scrollbarWidth, overflowY, scrollbarHeight, columnStore, editStore, isAllOverflow, expandColumn } = reactData
1836
- const { visibleColumn, fullColumnIdData, tableHeight, tableWidth, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData
1858
+ const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, overflowX, scrollbarWidth, overflowY, scrollbarHeight, scrollXWidth, columnStore, editStore, isAllOverflow, expandColumn } = reactData
1859
+ const { visibleColumn, fullColumnIdData, tableHeight, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData
1837
1860
  const el = refElem.value
1838
1861
  if (!el) {
1839
1862
  return
@@ -1873,9 +1896,10 @@ export default defineComponent({
1873
1896
  bodyHeight = Math.max(bodyMinHeight, bodyHeight)
1874
1897
  }
1875
1898
 
1899
+ const scrollbarXToTop = computeScrollbarXToTop.value
1900
+
1876
1901
  const xLeftCornerEl = refScrollXLeftCornerElem.value
1877
1902
  const xRightCornerEl = refScrollXRightCornerElem.value
1878
- const scrollbarXToTop = computeScrollbarXToTop.value
1879
1903
  const scrollXVirtualEl = refScrollXVirtualElem.value
1880
1904
  if (scrollXVirtualEl) {
1881
1905
  scrollXVirtualEl.style.height = `${osbHeight}px`
@@ -1970,7 +1994,7 @@ export default defineComponent({
1970
1994
  if (fixedType) {
1971
1995
  if (isGroup) {
1972
1996
  if (wrapperElem) {
1973
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
1997
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
1974
1998
  }
1975
1999
  } else {
1976
2000
  if (isOptimizeMode) {
@@ -1979,7 +2003,7 @@ export default defineComponent({
1979
2003
  }
1980
2004
  } else {
1981
2005
  if (wrapperElem) {
1982
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
2006
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
1983
2007
  }
1984
2008
  }
1985
2009
  }
@@ -2063,7 +2087,7 @@ export default defineComponent({
2063
2087
  }
2064
2088
  } else {
2065
2089
  if (wrapperElem) {
2066
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
2090
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
2067
2091
  }
2068
2092
  }
2069
2093
  }
@@ -2105,7 +2129,7 @@ export default defineComponent({
2105
2129
  }
2106
2130
  } else {
2107
2131
  if (wrapperElem) {
2108
- wrapperElem.style.width = tableWidth ? `${tableWidth}px` : ''
2132
+ wrapperElem.style.width = scrollXWidth ? `${scrollXWidth}px` : ''
2109
2133
  }
2110
2134
  }
2111
2135
  }
@@ -2727,6 +2751,9 @@ export default defineComponent({
2727
2751
  calcCellWidth()
2728
2752
  autoCellWidth()
2729
2753
  updateStyle()
2754
+ if (reFull) {
2755
+ updateRowOffsetTop()
2756
+ }
2730
2757
  updateRowExpandStyle()
2731
2758
  return computeScrollLoad().then(() => {
2732
2759
  if (reFull === true) {
@@ -2734,6 +2761,9 @@ export default defineComponent({
2734
2761
  calcCellWidth()
2735
2762
  autoCellWidth()
2736
2763
  updateStyle()
2764
+ if (reFull) {
2765
+ updateRowOffsetTop()
2766
+ }
2737
2767
  updateRowExpandStyle()
2738
2768
  return computeScrollLoad()
2739
2769
  }
@@ -2875,6 +2905,7 @@ export default defineComponent({
2875
2905
  }
2876
2906
  reactData.isRowLoading = false
2877
2907
  calcCellHeight()
2908
+ updateRowOffsetTop()
2878
2909
  // 是否变更虚拟滚动
2879
2910
  if (oldScrollYLoad === sYLoad) {
2880
2911
  restoreScrollLocation($xeTable, targetScrollLeft, targetScrollTop)
@@ -2939,16 +2970,16 @@ export default defineComponent({
2939
2970
  }
2940
2971
 
2941
2972
  const loadScrollXData = () => {
2942
- const { mergeList, mergeFooterList } = reactData
2973
+ const { mergeList, mergeFooterList, isScrollXBig } = reactData
2943
2974
  const { scrollXStore } = internalData
2944
2975
  const { preloadSize, startIndex, endIndex, offsetSize } = scrollXStore
2945
2976
  const { toVisibleIndex, visibleSize } = handleVirtualXVisible()
2946
2977
  const offsetItem = {
2947
- startIndex: Math.max(0, toVisibleIndex - 1 - offsetSize - preloadSize),
2948
- endIndex: toVisibleIndex + visibleSize + offsetSize + preloadSize
2978
+ startIndex: Math.max(0, isScrollXBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
2979
+ endIndex: isScrollXBig ? toVisibleIndex + visibleSize : toVisibleIndex + visibleSize + offsetSize + preloadSize
2949
2980
  }
2950
- scrollXStore.visibleStartIndex = toVisibleIndex
2951
- scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize
2981
+ scrollXStore.visibleStartIndex = toVisibleIndex - 1
2982
+ scrollXStore.visibleEndIndex = toVisibleIndex + visibleSize + 1
2952
2983
  calculateMergerOffsetIndex(mergeList.concat(mergeFooterList), offsetItem, 'col')
2953
2984
  const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem
2954
2985
  if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
@@ -3085,6 +3116,7 @@ export default defineComponent({
3085
3116
  internalData.visibleColumn = visibleColumn
3086
3117
  handleTableColumn()
3087
3118
  if (isReset) {
3119
+ updateColumnOffsetLeft()
3088
3120
  return $xeTable.updateFooter().then(() => {
3089
3121
  return $xeTable.recalculate()
3090
3122
  }).then(() => {
@@ -3260,18 +3292,18 @@ export default defineComponent({
3260
3292
  /**
3261
3293
  * 纵向 Y 可视渲染处理
3262
3294
  */
3263
- const loadScrollYData = (scrollTop?: number) => {
3264
- const { mergeList, isAllOverflow } = reactData
3295
+ const loadScrollYData = () => {
3296
+ const { mergeList, isAllOverflow, isScrollYBig } = reactData
3265
3297
  const { scrollYStore } = internalData
3266
3298
  const { preloadSize, startIndex, endIndex, offsetSize } = scrollYStore
3267
3299
  const autoOffsetYSize = isAllOverflow ? offsetSize : offsetSize + 1
3268
- const { toVisibleIndex, visibleSize } = handleVirtualYVisible(scrollTop)
3300
+ const { toVisibleIndex, visibleSize } = handleVirtualYVisible()
3269
3301
  const offsetItem = {
3270
- startIndex: Math.max(0, toVisibleIndex - 1 - offsetSize - preloadSize),
3271
- endIndex: toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize
3302
+ startIndex: Math.max(0, isScrollYBig ? toVisibleIndex - 1 : toVisibleIndex - 1 - offsetSize - preloadSize),
3303
+ endIndex: isScrollYBig ? (toVisibleIndex + visibleSize) : (toVisibleIndex + visibleSize + autoOffsetYSize + preloadSize)
3272
3304
  }
3273
- scrollYStore.visibleStartIndex = toVisibleIndex
3274
- scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize
3305
+ scrollYStore.visibleStartIndex = toVisibleIndex - 1
3306
+ scrollYStore.visibleEndIndex = toVisibleIndex + visibleSize + 1
3275
3307
  calculateMergerOffsetIndex(mergeList, offsetItem, 'row')
3276
3308
  const { startIndex: offsetStartIndex, endIndex: offsetEndIndex } = offsetItem
3277
3309
  if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
@@ -3373,6 +3405,7 @@ export default defineComponent({
3373
3405
  $xeTable.updateScrollYSpace()
3374
3406
  })
3375
3407
  }
3408
+ updateRowExpandStyle()
3376
3409
  $xeTable.updateCellAreas()
3377
3410
  }, 200)
3378
3411
  }
@@ -3463,47 +3496,76 @@ export default defineComponent({
3463
3496
  })
3464
3497
  }
3465
3498
 
3499
+ const updateColumnOffsetLeft = () => {
3500
+ const { visibleColumn, fullColumnIdData } = internalData
3501
+ let offsetLeft = 0
3502
+ for (let cIndex = 0, rLen = visibleColumn.length; cIndex < rLen; cIndex++) {
3503
+ const column = visibleColumn[cIndex]
3504
+ const colid = column.id
3505
+ const colRest = fullColumnIdData[colid]
3506
+ colRest.oLeft = offsetLeft
3507
+ offsetLeft += column.renderWidth
3508
+ }
3509
+ }
3510
+
3511
+ const updateRowOffsetTop = () => {
3512
+ const { expandColumn, rowExpandedMaps } = reactData
3513
+ const { afterFullData, fullAllDataRowIdData } = internalData
3514
+ const expandOpts = computeExpandOpts.value
3515
+ const rowOpts = computeRowOpts.value
3516
+ const cellOpts = computeCellOpts.value
3517
+ const defaultRowHeight = computeDefaultRowHeight.value
3518
+ let offsetTop = 0
3519
+ for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
3520
+ const row = afterFullData[rIndex]
3521
+ const rowid = getRowid($xeTable, row)
3522
+ const rowRest = fullAllDataRowIdData[rowid] || {}
3523
+ rowRest.oTop = offsetTop
3524
+ offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
3525
+ // 是否展开行
3526
+ if (expandColumn && rowExpandedMaps[rowid]) {
3527
+ offsetTop += rowRest.expandHeight || expandOpts.height || 0
3528
+ }
3529
+ }
3530
+ }
3531
+
3466
3532
  const updateRowExpandStyle = () => {
3467
- const { expandColumn, scrollYLoad, rowExpandedMaps } = reactData
3533
+ const { expandColumn, scrollYLoad, scrollYTop, isScrollYBig } = reactData
3468
3534
  const expandOpts = computeExpandOpts.value
3469
3535
  const rowOpts = computeRowOpts.value
3470
3536
  const cellOpts = computeCellOpts.value
3471
3537
  const defaultRowHeight = computeDefaultRowHeight.value
3472
3538
  const { mode } = expandOpts
3473
3539
  if (expandColumn && mode === 'fixed') {
3474
- const { elemStore, afterFullData, fullAllDataRowIdData } = internalData
3540
+ const { elemStore, fullAllDataRowIdData } = internalData
3475
3541
  const rowExpandEl = refRowExpandElem.value
3476
3542
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
3477
3543
  if (rowExpandEl && bodyScrollElem) {
3478
3544
  let isUpdateHeight = false
3479
- if (scrollYLoad) {
3480
- let offsetTop = 0
3481
- for (let rIndex = 0, rLen = afterFullData.length; rIndex < rLen; rIndex++) {
3482
- const row = afterFullData[rIndex]
3483
- const rowid = getRowid($xeTable, row)
3484
- const rowRest = fullAllDataRowIdData[rowid] || {}
3485
- rowRest.oTop = offsetTop
3486
- offsetTop += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
3487
- // 是否展开行
3488
- if (expandColumn && rowExpandedMaps[rowid]) {
3489
- offsetTop += rowRest.expandHeight || expandOpts.height || 0
3490
- }
3491
- }
3492
- }
3493
3545
  XEUtils.arrayEach(rowExpandEl.children, reEl => {
3494
3546
  const expandEl = reEl as HTMLDivElement
3495
3547
  const rowid = expandEl.getAttribute('rowid') || ''
3496
3548
  const rowRest = fullAllDataRowIdData[rowid]
3497
3549
  if (rowRest) {
3498
3550
  const expandHeight = expandEl.offsetHeight + 1
3551
+ const trEl = bodyScrollElem.querySelector(`.vxe-body--row[rowid="${rowid}"]`) as HTMLTableCellElement
3552
+ let offsetTop = 0
3499
3553
  if (scrollYLoad) {
3500
- expandEl.style.top = toCssUnit(rowRest.oTop + (rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight))
3554
+ if (isScrollYBig && trEl) {
3555
+ offsetTop = trEl.offsetTop + trEl.offsetHeight
3556
+ } else {
3557
+ offsetTop = rowRest.oTop + (rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight)
3558
+ }
3501
3559
  } else {
3502
- const trEl = bodyScrollElem.querySelector(`.vxe-body--row[rowid="${rowid}"]`) as HTMLTableCellElement
3503
3560
  if (trEl) {
3504
- expandEl.style.top = toCssUnit(trEl.offsetTop + trEl.offsetHeight)
3561
+ offsetTop = trEl.offsetTop + trEl.offsetHeight
3505
3562
  }
3506
3563
  }
3564
+ if (isScrollYBig) {
3565
+ offsetTop += scrollYTop
3566
+ }
3567
+ expandEl.style.top = toCssUnit(offsetTop)
3568
+
3507
3569
  if (!isUpdateHeight) {
3508
3570
  if (rowRest.expandHeight !== expandHeight) {
3509
3571
  isUpdateHeight = true
@@ -3514,6 +3576,9 @@ export default defineComponent({
3514
3576
  })
3515
3577
  if (isUpdateHeight) {
3516
3578
  reactData.rowExpandHeightFlag++
3579
+ nextTick(() => {
3580
+ updateRowOffsetTop()
3581
+ })
3517
3582
  }
3518
3583
  }
3519
3584
  }
@@ -4422,6 +4487,7 @@ export default defineComponent({
4422
4487
  }
4423
4488
  }
4424
4489
  return nextTick().then(() => {
4490
+ updateRowOffsetTop()
4425
4491
  return { status }
4426
4492
  })
4427
4493
  },
@@ -5289,12 +5355,12 @@ export default defineComponent({
5289
5355
  }
5290
5356
  reactData.rowExpandedMaps = rExpandedMaps
5291
5357
  return Promise.all(lazyRests)
5292
- .then(() => $xeTable.recalculate())
5358
+ .then(() => nextTick())
5359
+ .then(() => $xeTable.recalculate(true))
5293
5360
  .then(() => {
5294
- if (expandColumn) {
5295
- updateRowExpandStyle()
5296
- handleRowExpandScroll()
5297
- }
5361
+ updateRowOffsetTop()
5362
+ updateRowExpandStyle()
5363
+ handleRowExpandScroll()
5298
5364
  return $xeTable.updateCellAreas()
5299
5365
  })
5300
5366
  },
@@ -5321,16 +5387,21 @@ export default defineComponent({
5321
5387
  const { tableFullData } = internalData
5322
5388
  const expandOpts = computeExpandOpts.value
5323
5389
  const { reserve } = expandOpts
5324
- const expList = tableMethods.getRowExpandRecords()
5390
+ const expList = $xeTable.getRowExpandRecords()
5325
5391
  reactData.rowExpandedMaps = {}
5326
5392
  if (reserve) {
5327
5393
  tableFullData.forEach((row) => handleRowExpandReserve(row, false))
5328
5394
  }
5329
5395
  return nextTick().then(() => {
5330
5396
  if (expList.length) {
5331
- tableMethods.recalculate()
5397
+ return $xeTable.recalculate(true)
5332
5398
  }
5333
- }).then(() => $xeTable.updateCellAreas())
5399
+ }).then(() => {
5400
+ updateRowOffsetTop()
5401
+ updateRowExpandStyle()
5402
+ handleRowExpandScroll()
5403
+ return $xeTable.updateCellAreas()
5404
+ })
5334
5405
  },
5335
5406
  clearRowExpandReserve () {
5336
5407
  internalData.rowExpandedReserveRowMap = {}
@@ -6524,8 +6595,8 @@ export default defineComponent({
6524
6595
  const wrapperRect = el.getBoundingClientRect()
6525
6596
  const osbWidth = overflowY ? scrollbarWidth : 0
6526
6597
  const osbHeight = overflowX ? scrollbarHeight : 0
6527
- const tableWidth = el.clientWidth
6528
- const tableHeight = el.clientHeight
6598
+ const tableWrapperWidth = el.clientWidth
6599
+ const tableWrapperHeight = el.clientHeight
6529
6600
  if (trEl) {
6530
6601
  const rdLineEl = refDragRowLineElem.value
6531
6602
  if (rdLineEl) {
@@ -6534,14 +6605,14 @@ export default defineComponent({
6534
6605
  const trRect = trEl.getBoundingClientRect()
6535
6606
  let trHeight = trEl.clientHeight
6536
6607
  const offsetTop = Math.max(1, trRect.y - wrapperRect.y)
6537
- if (offsetTop + trHeight > tableHeight - osbHeight) {
6538
- trHeight = tableHeight - offsetTop - osbHeight
6608
+ if (offsetTop + trHeight > tableWrapperHeight - osbHeight) {
6609
+ trHeight = tableWrapperHeight - offsetTop - osbHeight
6539
6610
  }
6540
6611
  rdLineEl.style.display = 'block'
6541
6612
  rdLineEl.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`
6542
6613
  rdLineEl.style.top = `${offsetTop}px`
6543
6614
  rdLineEl.style.height = `${trHeight}px`
6544
- rdLineEl.style.width = `${tableWidth - osbWidth}px`
6615
+ rdLineEl.style.width = `${tableWrapperWidth - osbWidth}px`
6545
6616
  rdLineEl.setAttribute('drag-pos', dragPos)
6546
6617
  rdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
6547
6618
  } else {
@@ -6566,7 +6637,7 @@ export default defineComponent({
6566
6637
  thWidth -= startX - offsetLeft
6567
6638
  offsetLeft = startX
6568
6639
  }
6569
- const endX = tableWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth)
6640
+ const endX = tableWrapperWidth - rightContainerWidth - (rightContainerWidth ? 0 : osbWidth)
6570
6641
  if (offsetLeft + thWidth > endX) {
6571
6642
  thWidth = endX - offsetLeft
6572
6643
  }
@@ -6577,7 +6648,7 @@ export default defineComponent({
6577
6648
  if (prevDragToChild) {
6578
6649
  cdLineEl.style.height = `${thRect.height}px`
6579
6650
  } else {
6580
- cdLineEl.style.height = `${tableHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`
6651
+ cdLineEl.style.height = `${tableWrapperHeight - offsetTop - (scrollbarXToTop ? 0 : osbHeight)}px`
6581
6652
  }
6582
6653
  cdLineEl.setAttribute('drag-pos', dragPos)
6583
6654
  cdLineEl.setAttribute('drag-to-child', prevDragToChild ? 'y' : 'n')
@@ -6965,7 +7036,7 @@ export default defineComponent({
6965
7036
  resizeBarElem.style.height = `${scrollbarXToTop ? tableHeight - osbHeight : tableHeight}px`
6966
7037
  if (resizableOpts.showDragTip && resizeTipElem) {
6967
7038
  resizeTipElem.textContent = getI18n('vxe.table.resizeColTip', [resizeColumn.renderWidth + (isRightFixed ? dragPosLeft - dragLeft : dragLeft - dragPosLeft)])
6968
- const tableWidth = tableEl.clientWidth
7039
+ const tableWrapperWidth = tableEl.clientWidth
6969
7040
  const wrapperRect = wrapperElem.getBoundingClientRect()
6970
7041
  const resizeBarWidth = resizeBarElem.clientWidth
6971
7042
  const resizeTipWidth = resizeTipElem.clientWidth
@@ -6973,8 +7044,8 @@ export default defineComponent({
6973
7044
  let resizeTipLeft = -resizeTipWidth
6974
7045
  if (resizeBarLeft < resizeTipWidth + resizeBarWidth) {
6975
7046
  resizeTipLeft = 0
6976
- } else if (resizeBarLeft > tableWidth) {
6977
- resizeTipLeft += tableWidth - resizeBarLeft
7047
+ } else if (resizeBarLeft > tableWrapperWidth) {
7048
+ resizeTipLeft += tableWrapperWidth - resizeBarLeft
6978
7049
  }
6979
7050
  resizeTipElem.style.left = `${resizeTipLeft}px`
6980
7051
  resizeTipElem.style.top = `${Math.min(tableHeight - resizeTipHeight, Math.max(0, evnt.clientY - wrapperRect.y - resizeTipHeight / 2))}px`
@@ -7110,7 +7181,7 @@ export default defineComponent({
7110
7181
  const updateEvent = (evnt: MouseEvent) => {
7111
7182
  evnt.stopPropagation()
7112
7183
  evnt.preventDefault()
7113
- const tableWidth = tableEl.clientWidth - osbWidth
7184
+ const rtWidth = tableEl.clientWidth - osbWidth
7114
7185
  const tableHeight = tableEl.clientHeight - osbHeight
7115
7186
  let dragTop = evnt.clientY - tableRect.y - targetOffsetY
7116
7187
  if (dragTop < minTop) {
@@ -7120,15 +7191,15 @@ export default defineComponent({
7120
7191
  }
7121
7192
  resizeBarElem.style.left = `${scrollbarYToLeft ? osbWidth : 0}px`
7122
7193
  resizeBarElem.style.top = `${dragTop}px`
7123
- resizeBarElem.style.width = `${tableWidth}px`
7194
+ resizeBarElem.style.width = `${rtWidth}px`
7124
7195
  if (resizableOpts.showDragTip && resizeTipElem) {
7125
7196
  resizeTipElem.textContent = getI18n('vxe.table.resizeRowTip', [resizeHeight])
7126
7197
  const resizeTipWidth = resizeTipElem.clientWidth
7127
7198
  const resizeTipHeight = resizeTipElem.clientHeight
7128
7199
  let resizeBarLeft = Math.max(2, evnt.clientX - tableRect.x)
7129
7200
  let resizeBarTop = 0
7130
- if (resizeBarLeft + resizeTipWidth >= tableWidth - 2) {
7131
- resizeBarLeft = tableWidth - resizeTipWidth - 2
7201
+ if (resizeBarLeft + resizeTipWidth >= rtWidth - 2) {
7202
+ resizeBarLeft = rtWidth - resizeTipWidth - 2
7132
7203
  }
7133
7204
  if (dragTop + resizeTipHeight >= tableHeight) {
7134
7205
  resizeBarTop = tableHeight - (dragTop + resizeTipHeight)
@@ -7161,6 +7232,7 @@ export default defineComponent({
7161
7232
  } else {
7162
7233
  rowRest.resizeHeight = resizeHeight
7163
7234
  handleUpdateRowResize(evnt, resizeParams)
7235
+ updateRowOffsetTop()
7164
7236
  }
7165
7237
  }
7166
7238
  removeClass(tableEl, 'row-drag--resize')
@@ -7388,8 +7460,8 @@ export default defineComponent({
7388
7460
  const { treeConfig } = props
7389
7461
  const { selectCheckboxMaps, treeIndeterminateMaps } = reactData
7390
7462
  const checkboxOpts = computeCheckboxOpts.value
7391
- const { checkField, checkMethod } = checkboxOpts
7392
- const { afterFullData, afterTreeFullData } = internalData
7463
+ const { checkField, checkMethod, showReserveStatus } = checkboxOpts
7464
+ const { afterFullData, afterTreeFullData, checkboxReserveRowMap } = internalData
7393
7465
 
7394
7466
  let sLen = 0 // 已选
7395
7467
  let hLen = 0 // 半选
@@ -7427,7 +7499,12 @@ export default defineComponent({
7427
7499
  })
7428
7500
 
7429
7501
  const isSelected = rootList.length > 0 ? (vLen > 0 ? (sLen >= vLen) : (sLen >= rootList.length)) : false
7430
- const halfSelect = !isSelected && (sLen >= 1 || hLen >= 1)
7502
+ let halfSelect = !isSelected && (sLen >= 1 || hLen >= 1)
7503
+
7504
+ // 如果复选框启用保留记录,当保留数据存在时显示半选
7505
+ if (!isSelected && !halfSelect && showReserveStatus) {
7506
+ halfSelect = !XEUtils.isEmpty(checkboxReserveRowMap)
7507
+ }
7431
7508
 
7432
7509
  reactData.isAllSelected = isSelected
7433
7510
  reactData.isIndeterminate = halfSelect
@@ -8604,21 +8681,21 @@ export default defineComponent({
8604
8681
  const scrollTargetEl = xHandleEl || tableBodyElem
8605
8682
  if (scrollTargetEl) {
8606
8683
  const wrapperRect = el.getBoundingClientRect()
8607
- const tableWidth = el.clientWidth
8684
+ const tableWrapperWidth = el.clientWidth
8608
8685
  const leftContainerElem = refLeftContainer.value
8609
8686
  const leftContainerWidth = leftContainerElem ? leftContainerElem.clientWidth : 0
8610
8687
  const rightContainerElem = refRightContainer.value
8611
8688
  const rightContainerWidth = rightContainerElem ? rightContainerElem.clientWidth : 0
8612
8689
  const srartX = wrapperRect.x + leftContainerWidth
8613
- const endX = wrapperRect.x + tableWidth - rightContainerWidth
8690
+ const endX = wrapperRect.x + tableWrapperWidth - rightContainerWidth
8614
8691
  const distSize = 28
8615
8692
  const startDistSize = clientX - srartX
8616
8693
  const endDistSize = endX - clientX
8617
8694
  if (startDistSize > 0 && startDistSize <= distSize) {
8618
- const scrollRatio = Math.floor(tableWidth / (startDistSize > distSize / 2 ? 240 : 120))
8695
+ const scrollRatio = Math.floor(tableWrapperWidth / (startDistSize > distSize / 2 ? 240 : 120))
8619
8696
  scrollTargetEl.scrollLeft -= scrollRatio * (distSize - startDistSize)
8620
8697
  } else if (endDistSize > 0 && endDistSize <= distSize) {
8621
- const scrollRatio = Math.floor(tableWidth / (endDistSize > distSize / 2 ? 240 : 120))
8698
+ const scrollRatio = Math.floor(tableWrapperWidth / (endDistSize > distSize / 2 ? 240 : 120))
8622
8699
  scrollTargetEl.scrollLeft += scrollRatio * (distSize - endDistSize)
8623
8700
  }
8624
8701
  }
@@ -9118,43 +9195,70 @@ export default defineComponent({
9118
9195
  updateScrollYStatus,
9119
9196
  // 更新横向 X 可视渲染上下剩余空间大小
9120
9197
  updateScrollXSpace () {
9121
- const { isGroup, scrollXLoad, overflowX } = reactData
9122
- const { visibleColumn, scrollXStore, elemStore, tableWidth } = internalData
9123
- const tableHeader = refTableHeader.value
9198
+ const { isGroup, scrollXLoad, overflowX, scrollXWidth } = reactData
9199
+ const { visibleColumn, scrollXStore, elemStore, fullColumnIdData } = internalData
9124
9200
  const tableBody = refTableBody.value
9125
- const tableFooter = refTableFooter.value
9126
9201
  const tableBodyElem = tableBody ? tableBody.$el as HTMLDivElement : null
9127
9202
  if (tableBodyElem) {
9128
- const tableHeaderElem = tableHeader ? tableHeader.$el as HTMLDivElement : null
9129
- const tableFooterElem = tableFooter ? tableFooter.$el as HTMLDivElement : null
9130
- const headerElem = tableHeaderElem ? tableHeaderElem.querySelector('.vxe-table--header') as HTMLTableElement : null
9131
- const bodyElem = tableBodyElem.querySelector('.vxe-table--body') as HTMLTableElement
9132
- const footerElem = tableFooterElem ? tableFooterElem.querySelector('.vxe-table--footer') as HTMLTableElement : null
9133
- const leftSpaceWidth = visibleColumn.slice(0, scrollXStore.startIndex).reduce((previous, column) => previous + column.renderWidth, 0)
9203
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
9204
+ const bodyTableElem = getRefElem(elemStore['main-body-table'])
9205
+ const headerTableElem = getRefElem(elemStore['main-header-table'])
9206
+ const footerTableElem = getRefElem(elemStore['main-footer-table'])
9207
+
9208
+ let xSpaceLeft = 0
9209
+ const firstColumn = visibleColumn[scrollXStore.startIndex]
9210
+ if (firstColumn) {
9211
+ const colRest = fullColumnIdData[firstColumn.id] || {}
9212
+ xSpaceLeft = colRest.oLeft
9213
+ }
9214
+
9215
+ let clientWidth = 0
9216
+ if (bodyScrollElem) {
9217
+ clientWidth = bodyScrollElem.clientWidth
9218
+ }
9219
+ // 虚拟渲染
9220
+ let isScrollXBig = false
9221
+ let ySpaceWidth = scrollXWidth
9222
+ if (scrollXWidth > maxXWidth) {
9223
+ // 触右
9224
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
9225
+ xSpaceLeft = maxXWidth - bodyTableElem.clientWidth
9226
+ } else {
9227
+ xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth))
9228
+ }
9229
+ ySpaceWidth = maxXWidth
9230
+ isScrollXBig = true
9231
+ }
9232
+
9134
9233
  let marginLeft = ''
9135
9234
  if (scrollXLoad && overflowX) {
9136
- marginLeft = `${leftSpaceWidth}px`
9235
+ marginLeft = `${xSpaceLeft}px`
9236
+ }
9237
+ if (headerTableElem) {
9238
+ headerTableElem.style.marginLeft = isGroup ? '' : marginLeft
9137
9239
  }
9138
- if (headerElem) {
9139
- headerElem.style.marginLeft = isGroup ? '' : marginLeft
9240
+ if (bodyTableElem) {
9241
+ bodyTableElem.style.marginLeft = marginLeft
9140
9242
  }
9141
- bodyElem.style.marginLeft = marginLeft
9142
- if (footerElem) {
9143
- footerElem.style.marginLeft = marginLeft
9243
+ if (footerTableElem) {
9244
+ footerTableElem.style.marginLeft = marginLeft
9144
9245
  }
9246
+
9247
+ reactData.isScrollXBig = isScrollXBig
9248
+
9145
9249
  const containerList = ['main']
9146
9250
  containerList.forEach(name => {
9147
9251
  const layoutList = ['header', 'body', 'footer']
9148
9252
  layoutList.forEach(layout => {
9149
9253
  const xSpaceElem = getRefElem(elemStore[`${name}-${layout}-xSpace`])
9150
9254
  if (xSpaceElem) {
9151
- xSpaceElem.style.width = scrollXLoad ? `${tableWidth}px` : ''
9255
+ xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : ''
9152
9256
  }
9153
9257
  })
9154
9258
  })
9155
9259
  const scrollXSpaceEl = refScrollXSpaceElem.value
9156
9260
  if (scrollXSpaceEl) {
9157
- scrollXSpaceEl.style.width = `${tableWidth}px`
9261
+ scrollXSpaceEl.style.width = `${ySpaceWidth}px`
9158
9262
  }
9159
9263
  nextTick(() => {
9160
9264
  updateStyle()
@@ -9170,48 +9274,64 @@ export default defineComponent({
9170
9274
  const rowOpts = computeRowOpts.value
9171
9275
  const cellOpts = computeCellOpts.value
9172
9276
  const defaultRowHeight = computeDefaultRowHeight.value
9277
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
9173
9278
  const bodyTableElem = getRefElem(elemStore['main-body-table'])
9174
9279
  const containerList = ['main', 'left', 'right']
9175
- let topSpaceHeight = 0
9176
- let ySpaceHeight = 0
9177
-
9280
+ let ySpaceTop = 0
9281
+ let scrollYHeight = 0
9282
+ let isScrollYBig = false
9178
9283
  if (scrollYLoad) {
9179
9284
  const isCustomCellHeight = isResizeCellHeight || cellOpts.height || rowOpts.height
9180
9285
  if (!isCustomCellHeight && !expandColumn && isAllOverflow) {
9181
- ySpaceHeight = afterFullData.length * defaultRowHeight
9182
- topSpaceHeight = Math.max(0, startIndex * defaultRowHeight)
9286
+ scrollYHeight = afterFullData.length * defaultRowHeight
9287
+ if (scrollYHeight > maxYHeight) {
9288
+ isScrollYBig = true
9289
+ }
9290
+ ySpaceTop = Math.max(0, startIndex * defaultRowHeight)
9183
9291
  } else {
9184
- for (let i = 0; i < afterFullData.length; i++) {
9185
- const row = afterFullData[i]
9186
- const rowid = getRowid($xeTable, row)
9187
- const rowRest = fullAllDataRowIdData[rowid] || {}
9188
- ySpaceHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
9189
- // 是否展开行
9190
- if (expandColumn && rowExpandedMaps[rowid]) {
9191
- ySpaceHeight += rowRest.expandHeight || expandOpts.height || 0
9192
- }
9292
+ const firstRow = afterFullData[startIndex]
9293
+ let rowid = getRowid($xeTable, firstRow)
9294
+ let rowRest = fullAllDataRowIdData[rowid] || {}
9295
+ ySpaceTop = rowRest.oTop
9296
+
9297
+ const lastRow = afterFullData[afterFullData.length - 1]
9298
+ rowid = getRowid($xeTable, lastRow)
9299
+ rowRest = fullAllDataRowIdData[rowid] || {}
9300
+ scrollYHeight = rowRest.oTop + (rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight)
9301
+ // 是否展开行
9302
+ if (expandColumn && rowExpandedMaps[rowid]) {
9303
+ scrollYHeight += rowRest.expandHeight || expandOpts.height || 0
9193
9304
  }
9194
- for (let i = 0; i < startIndex; i++) {
9195
- const row = afterFullData[i]
9196
- const rowid = getRowid($xeTable, row)
9197
- const rowRest = fullAllDataRowIdData[rowid] || {}
9198
- topSpaceHeight += rowRest.resizeHeight || cellOpts.height || rowOpts.height || rowRest.height || defaultRowHeight
9199
- // 是否展开行
9200
- if (expandColumn && rowExpandedMaps[rowid]) {
9201
- topSpaceHeight += rowRest.expandHeight || expandOpts.height || 0
9202
- }
9305
+ if (scrollYHeight > maxYHeight) {
9306
+ isScrollYBig = true
9203
9307
  }
9204
9308
  }
9205
9309
  } else {
9206
9310
  if (bodyTableElem) {
9207
- ySpaceHeight = bodyTableElem.clientHeight
9311
+ scrollYHeight = bodyTableElem.clientHeight
9312
+ }
9313
+ }
9314
+ let clientHeight = 0
9315
+ if (bodyScrollElem) {
9316
+ clientHeight = bodyScrollElem.clientHeight
9317
+ }
9318
+ // 虚拟渲染
9319
+ let ySpaceHeight = scrollYHeight
9320
+ let scrollYTop = ySpaceTop
9321
+ if (isScrollYBig) {
9322
+ // 触底
9323
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
9324
+ scrollYTop = maxYHeight - bodyTableElem.clientHeight
9325
+ } else {
9326
+ scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight))
9208
9327
  }
9328
+ ySpaceHeight = maxYHeight
9209
9329
  }
9210
9330
  containerList.forEach(name => {
9211
9331
  const layoutList = ['header', 'body', 'footer']
9212
9332
  const tableElem = getRefElem(elemStore[`${name}-body-table`])
9213
9333
  if (tableElem) {
9214
- tableElem.style.marginTop = topSpaceHeight ? `${topSpaceHeight}px` : ''
9334
+ tableElem.style.marginTop = scrollYTop ? `${scrollYTop}px` : ''
9215
9335
  }
9216
9336
  layoutList.forEach(layout => {
9217
9337
  const ySpaceElem = getRefElem(elemStore[`${name}-${layout}-ySpace`])
@@ -9228,6 +9348,9 @@ export default defineComponent({
9228
9348
  if (rowExpandYSpaceEl) {
9229
9349
  rowExpandYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : ''
9230
9350
  }
9351
+ reactData.scrollYTop = scrollYTop
9352
+ reactData.scrollYHeight = scrollYHeight
9353
+ reactData.isScrollYBig = isScrollYBig
9231
9354
  return nextTick().then(() => {
9232
9355
  updateStyle()
9233
9356
  })
@@ -10192,10 +10315,10 @@ export default defineComponent({
10192
10315
  }
10193
10316
  // 检查导入导出类型,如果自定义导入导出方法,则不校验类型
10194
10317
  if (importConfig && importOpts.types && !importOpts.importMethod && !XEUtils.includeArrays(XEUtils.keys(importOpts._typeMaps), importOpts.types)) {
10195
- warnLog('vxe.error.errProp', [`export-config.types=${importOpts.types.join(',')}`, importOpts.types.filter((type: string) => XEUtils.includes(XEUtils.keys(importOpts._typeMaps), type)).join(',') || XEUtils.keys(importOpts._typeMaps).join(',')])
10318
+ warnLog('vxe.error.errProp', [`export-config.types=${importOpts.types.join(',')}`, importOpts.types.filter((type) => XEUtils.includes(XEUtils.keys(importOpts._typeMaps), type)).join(',') || XEUtils.keys(importOpts._typeMaps).join(',')])
10196
10319
  }
10197
10320
  if (exportConfig && exportOpts.types && !exportOpts.exportMethod && !XEUtils.includeArrays(XEUtils.keys(exportOpts._typeMaps), exportOpts.types)) {
10198
- warnLog('vxe.error.errProp', [`export-config.types=${exportOpts.types.join(',')}`, exportOpts.types.filter((type: string) => XEUtils.includes(XEUtils.keys(exportOpts._typeMaps), type)).join(',') || XEUtils.keys(exportOpts._typeMaps).join(',')])
10321
+ warnLog('vxe.error.errProp', [`export-config.types=${exportOpts.types.join(',')}`, exportOpts.types.filter((type) => XEUtils.includes(XEUtils.keys(exportOpts._typeMaps), type)).join(',') || XEUtils.keys(exportOpts._typeMaps).join(',')])
10199
10322
  }
10200
10323
 
10201
10324
  if (!props.id) {
@@ -10209,7 +10332,7 @@ export default defineComponent({
10209
10332
  if (rowOpts.height && !props.showOverflow) {
10210
10333
  warnLog('vxe.error.notProp', ['table.show-overflow'])
10211
10334
  }
10212
- if (!($xeTable as any).handleMousedownCellAreaEvent) {
10335
+ if (!$xeTable.handleCellAreaMousedownEvent) {
10213
10336
  if (props.areaConfig) {
10214
10337
  warnLog('vxe.error.notProp', ['area-config'])
10215
10338
  }
@@ -10225,7 +10348,7 @@ export default defineComponent({
10225
10348
  }
10226
10349
  }
10227
10350
  if (treeConfig && rowOpts.drag && !treeOpts.transform) {
10228
- warnLog('vxe.error.notSupportProp', ['column-config.drag', 'tree-config.transform=false', 'tree-config.transform=true'])
10351
+ errLog('vxe.error.notSupportProp', ['column-config.drag', 'tree-config.transform=false', 'tree-config.transform=true'])
10229
10352
  }
10230
10353
  if (props.dragConfig) {
10231
10354
  warnLog('vxe.error.delProp', ['drag-config', 'row-drag-config'])