vue2-client 1.20.48 → 1.20.50
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.
package/package.json
CHANGED
|
@@ -489,8 +489,6 @@ export default {
|
|
|
489
489
|
// 行选择模式
|
|
490
490
|
selectRowMode: 'default',
|
|
491
491
|
tableSize: 'default',
|
|
492
|
-
/** 是否启用 tbody 虚拟滚动(配置 virtualScroll: true) */
|
|
493
|
-
virtualScroll: true,
|
|
494
492
|
clearSelectRowAfterQuery: false,
|
|
495
493
|
selectedRowModalVisible: false,
|
|
496
494
|
// 是否禁用右侧操作行为
|
|
@@ -888,7 +886,6 @@ export default {
|
|
|
888
886
|
printTemplate = 'DEFAULT_CRUD_PRINT_TEMPLATE',
|
|
889
887
|
selectRowMode = 'default',
|
|
890
888
|
tableSize = 'default',
|
|
891
|
-
virtualScroll = true,
|
|
892
889
|
clearSelectRowAfterQuery = false,
|
|
893
890
|
disableAction = false,
|
|
894
891
|
extraData,
|
|
@@ -955,7 +952,6 @@ export default {
|
|
|
955
952
|
this.chartsConfigArray = chartsConfigArray
|
|
956
953
|
this.selectRowMode = selectRowMode
|
|
957
954
|
this.tableSize = tableSize
|
|
958
|
-
this.virtualScroll = virtualScroll
|
|
959
955
|
this.clearSelectRowAfterQuery = clearSelectRowAfterQuery
|
|
960
956
|
this.disableAction = disableAction
|
|
961
957
|
this.extraData = extraData
|
|
@@ -1883,12 +1879,6 @@ export default {
|
|
|
1883
1879
|
color: @primary-color;
|
|
1884
1880
|
}
|
|
1885
1881
|
|
|
1886
|
-
.innerTable {
|
|
1887
|
-
:deep(.ant-form-item) {
|
|
1888
|
-
margin: 0;
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
1882
|
.hiddenFunctionalArea {
|
|
1893
1883
|
display: none;
|
|
1894
1884
|
}
|
|
@@ -374,7 +374,12 @@ export default {
|
|
|
374
374
|
}),
|
|
375
375
|
virtualScrollContainers: null,
|
|
376
376
|
virtualScrollResizeObserver: null,
|
|
377
|
-
|
|
377
|
+
/** 滚动:每帧最多一次 RAF,合并同帧内多次 scroll */
|
|
378
|
+
virtualScrollRafId: null,
|
|
379
|
+
/** 滚动时待处理的容器(与 RAF 配合,避免漏读 scrollTop) */
|
|
380
|
+
virtualScrollPendingTarget: null,
|
|
381
|
+
/** ResizeObserver 防抖定时器(窗口/侧栏拖拽时连续触发) */
|
|
382
|
+
virtualScrollResizeDebounceTimer: null
|
|
378
383
|
}
|
|
379
384
|
},
|
|
380
385
|
computed: {
|
|
@@ -416,9 +421,9 @@ export default {
|
|
|
416
421
|
// 3. 按顺序合并:左固定 + 普通 + 右固定
|
|
417
422
|
return [...leftFixedColumns, ...normalColumns, ...rightFixedColumns]
|
|
418
423
|
},
|
|
419
|
-
/**
|
|
424
|
+
/** 默认开启虚拟滚动;有行展开栅格时行高不可预测,关闭虚拟滚动 */
|
|
420
425
|
enableVirtualScroll () {
|
|
421
|
-
return
|
|
426
|
+
return !this.tableContext.expandedGrid
|
|
422
427
|
},
|
|
423
428
|
components () {
|
|
424
429
|
const headerCell = (h, props, children) => {
|
|
@@ -692,21 +697,60 @@ export default {
|
|
|
692
697
|
},
|
|
693
698
|
handleVirtualScroll (e) {
|
|
694
699
|
if (!this.enableVirtualScroll) return
|
|
695
|
-
|
|
700
|
+
this.virtualScrollPendingTarget = e.target
|
|
701
|
+
this.scheduleVirtualScrollRaf()
|
|
702
|
+
},
|
|
703
|
+
/** 将多次 scroll 合并到同一帧 RAF;若 flush 后又产生 pending 则再排一帧 */
|
|
704
|
+
scheduleVirtualScrollRaf () {
|
|
705
|
+
if (this.virtualScrollRafId != null) return
|
|
696
706
|
this.virtualScrollRafId = requestAnimationFrame(() => {
|
|
697
707
|
this.virtualScrollRafId = null
|
|
698
|
-
this.
|
|
708
|
+
this.flushVirtualScrollPending()
|
|
699
709
|
})
|
|
700
710
|
},
|
|
711
|
+
flushVirtualScrollPending () {
|
|
712
|
+
const container = this.virtualScrollPendingTarget
|
|
713
|
+
this.virtualScrollPendingTarget = null
|
|
714
|
+
if (container && this.enableVirtualScroll) {
|
|
715
|
+
this.applyVirtualWindowFromScroll(container)
|
|
716
|
+
}
|
|
717
|
+
if (this.virtualScrollPendingTarget) {
|
|
718
|
+
this.scheduleVirtualScrollRaf()
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
/** ResizeObserver 防抖 + 下一帧再测行高,避免拖拽窗口时连续重算 */
|
|
722
|
+
scheduleVirtualScrollResizeFlush () {
|
|
723
|
+
if (this.virtualScrollResizeDebounceTimer != null) {
|
|
724
|
+
clearTimeout(this.virtualScrollResizeDebounceTimer)
|
|
725
|
+
}
|
|
726
|
+
this.virtualScrollResizeDebounceTimer = setTimeout(() => {
|
|
727
|
+
this.virtualScrollResizeDebounceTimer = null
|
|
728
|
+
if (!this.enableVirtualScroll) return
|
|
729
|
+
requestAnimationFrame(() => {
|
|
730
|
+
if (!this.enableVirtualScroll) return
|
|
731
|
+
this.measureRowHeight()
|
|
732
|
+
const c = this.getScrollContainers()[0]
|
|
733
|
+
if (c) {
|
|
734
|
+
this.applyVirtualWindowFromScroll(c)
|
|
735
|
+
}
|
|
736
|
+
})
|
|
737
|
+
}, 80)
|
|
738
|
+
},
|
|
739
|
+
/** 可视区上下多渲染的行数:缓解行高误差与快速滚动时的白屏 */
|
|
740
|
+
getVirtualOverscanRows (clientH, rh) {
|
|
741
|
+
const base = Math.max(1, rh || 54)
|
|
742
|
+
// 约 2.5 倍视口行数,至少 12 行,避免快速滑动时空窗
|
|
743
|
+
return Math.ceil(Math.max((clientH / base) * 2.5, 12))
|
|
744
|
+
},
|
|
701
745
|
applyVirtualWindowFromScroll (container) {
|
|
702
746
|
if (!container || !this.enableVirtualScroll) return
|
|
703
747
|
const vs = this.virtualState
|
|
704
|
-
const rh = vs.rowHeight || 54
|
|
748
|
+
const rh = Math.max(32, vs.rowHeight || 54)
|
|
705
749
|
const scrollTop = container.scrollTop
|
|
706
750
|
const clientH = container.clientHeight || 400
|
|
707
751
|
const total = vs.total
|
|
708
752
|
if (total <= 0) return
|
|
709
|
-
const overscan =
|
|
753
|
+
const overscan = this.getVirtualOverscanRows(clientH, rh)
|
|
710
754
|
const start = Math.max(0, Math.floor(scrollTop / rh) - overscan)
|
|
711
755
|
const viewportRows = Math.ceil(clientH / rh) + overscan * 2
|
|
712
756
|
const end = Math.min(total, start + viewportRows)
|
|
@@ -731,11 +775,25 @@ export default {
|
|
|
731
775
|
measureRowHeight () {
|
|
732
776
|
if (!this.enableVirtualScroll || !this.$el) return
|
|
733
777
|
this.$nextTick(() => {
|
|
734
|
-
const
|
|
735
|
-
if (!
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
778
|
+
const rows = this.$el.querySelectorAll('.ant-table-tbody tr.ant-table-row')
|
|
779
|
+
if (!rows || !rows.length) return
|
|
780
|
+
let maxH = 0
|
|
781
|
+
const n = Math.min(rows.length, 5)
|
|
782
|
+
for (let i = 0; i < n; i++) {
|
|
783
|
+
if (rows[i].classList.contains('x-table-virt-spacer')) continue
|
|
784
|
+
const h = rows[i].getBoundingClientRect().height
|
|
785
|
+
if (h > maxH) maxH = h
|
|
786
|
+
}
|
|
787
|
+
if (maxH > 0) {
|
|
788
|
+
// 取前若干行最大高度并向上取整,略低估行高会导致 start 偏大、底部留白
|
|
789
|
+
const next = Math.ceil(maxH)
|
|
790
|
+
if (Math.abs(next - this.virtualState.rowHeight) > 0.5) {
|
|
791
|
+
this.virtualState.rowHeight = next
|
|
792
|
+
const c = this.getScrollContainers()[0]
|
|
793
|
+
if (c) {
|
|
794
|
+
this.applyVirtualWindowFromScroll(c)
|
|
795
|
+
}
|
|
796
|
+
}
|
|
739
797
|
}
|
|
740
798
|
})
|
|
741
799
|
},
|
|
@@ -747,8 +805,8 @@ export default {
|
|
|
747
805
|
vs.start = 0
|
|
748
806
|
const containers = this.getScrollContainers()
|
|
749
807
|
const ch = containers[0]?.clientHeight || 400
|
|
750
|
-
const rh = vs.rowHeight || 54
|
|
751
|
-
const overscan =
|
|
808
|
+
const rh = Math.max(32, vs.rowHeight || 54)
|
|
809
|
+
const overscan = this.getVirtualOverscanRows(ch, rh)
|
|
752
810
|
const viewportRows = Math.ceil(ch / rh) + overscan * 2
|
|
753
811
|
vs.end = Math.min(total, Math.max(viewportRows, 1))
|
|
754
812
|
this.$nextTick(() => {
|
|
@@ -774,11 +832,7 @@ export default {
|
|
|
774
832
|
this.virtualScrollContainers = containers
|
|
775
833
|
if (typeof ResizeObserver !== 'undefined' && containers[0]) {
|
|
776
834
|
this.virtualScrollResizeObserver = new ResizeObserver(() => {
|
|
777
|
-
this.
|
|
778
|
-
const c = this.getScrollContainers()[0]
|
|
779
|
-
if (c) {
|
|
780
|
-
this.applyVirtualWindowFromScroll(c)
|
|
781
|
-
}
|
|
835
|
+
this.scheduleVirtualScrollResizeFlush()
|
|
782
836
|
})
|
|
783
837
|
this.virtualScrollResizeObserver.observe(containers[0])
|
|
784
838
|
}
|
|
@@ -796,10 +850,15 @@ export default {
|
|
|
796
850
|
this.virtualScrollResizeObserver.disconnect()
|
|
797
851
|
this.virtualScrollResizeObserver = null
|
|
798
852
|
}
|
|
799
|
-
if (this.virtualScrollRafId) {
|
|
853
|
+
if (this.virtualScrollRafId != null) {
|
|
800
854
|
cancelAnimationFrame(this.virtualScrollRafId)
|
|
801
855
|
this.virtualScrollRafId = null
|
|
802
856
|
}
|
|
857
|
+
if (this.virtualScrollResizeDebounceTimer != null) {
|
|
858
|
+
clearTimeout(this.virtualScrollResizeDebounceTimer)
|
|
859
|
+
this.virtualScrollResizeDebounceTimer = null
|
|
860
|
+
}
|
|
861
|
+
this.virtualScrollPendingTarget = null
|
|
803
862
|
},
|
|
804
863
|
handleRowClick (record) {
|
|
805
864
|
this.$emit('rowClick', record)
|
|
@@ -824,11 +883,6 @@ export default {
|
|
|
824
883
|
}
|
|
825
884
|
},
|
|
826
885
|
loadSelectedDataGen (requestParameters) {
|
|
827
|
-
console.log('loadSelectedDataGen', {
|
|
828
|
-
pageNo: requestParameters?.pageNo,
|
|
829
|
-
pageSize: requestParameters?.pageSize
|
|
830
|
-
})
|
|
831
|
-
|
|
832
886
|
const { pageNo = 1, pageSize = 10 } = requestParameters || {}
|
|
833
887
|
const startIndex = (pageNo - 1) * pageSize
|
|
834
888
|
const endIndex = startIndex + pageSize
|
|
@@ -988,6 +1042,18 @@ export default {
|
|
|
988
1042
|
:deep(.ant-pagination > li) {
|
|
989
1043
|
white-space: nowrap;
|
|
990
1044
|
}
|
|
1045
|
+
.innerTable {
|
|
1046
|
+
// 行编辑表格输入项样式
|
|
1047
|
+
:deep(.ant-form-item) {
|
|
1048
|
+
margin: 0;
|
|
1049
|
+
.ant-form-item-control-wrapper {
|
|
1050
|
+
width: 100%;
|
|
1051
|
+
}
|
|
1052
|
+
.ant-select {
|
|
1053
|
+
width: 100%;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
991
1057
|
</style>
|
|
992
1058
|
<style>
|
|
993
1059
|
/* 多操作下拉菜单边框与阴影 */
|