From 36b1ac8edae63e982b7f136d59427f218f5ad915 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Sat, 9 May 2026 17:39:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(grid):=20=E7=BF=BB=E9=A1=B5=E5=90=8E?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E8=A1=A8=E6=A0=BC=E6=BB=9A=E5=8A=A8=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/grid/DataGrid.vue | 46 +++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/components/grid/DataGrid.vue b/src/components/grid/DataGrid.vue index a33efddbc3..8dc46e0c3d 100644 --- a/src/components/grid/DataGrid.vue +++ b/src/components/grid/DataGrid.vue @@ -689,16 +689,19 @@ function currentOrderBy(): string | undefined { function prevPage() { if (currentPage.value <= 1) return; currentPage.value--; + resetGridVerticalScroll(true); emit("paginate", (currentPage.value - 1) * pageSize.value, pageSize.value, currentWhereInput(), currentOrderBy()); } function nextPage() { if (!isFullPage.value) return; currentPage.value++; + resetGridVerticalScroll(true); emit("paginate", (currentPage.value - 1) * pageSize.value, pageSize.value, currentWhereInput(), currentOrderBy()); } function changePageSize(size: number) { pageSize.value = size; currentPage.value = 1; + resetGridVerticalScroll(true); emit("paginate", 0, size, currentWhereInput(), currentOrderBy()); } @@ -706,7 +709,16 @@ function changePageSize(size: number) { type CellValue = string | number | boolean | null; const editingCell = ref<{ rowId: number; col: number } | null>(null); const editValue = ref(""); -const scrollerRef = ref(null); +type GridScrollerRef = + | HTMLElement + | { + $el?: HTMLElement; + el?: HTMLElement | { value?: HTMLElement }; + scrollToItem?: (index: number) => void; + scrollToPosition?: (position: number) => void; + }; + +const scrollerRef = ref(null); const dirtyRows = ref>>(new Map()); const newRows = ref([]); const deletedRows = ref>(new Set()); @@ -1105,6 +1117,8 @@ function setRowStatusFilter(value: string) { // --- Inline editor --- let isCancelling = false; let cancelScrollRestoreFrame = 0; +let resetScrollFrame = 0; +let resetScrollAfterResult = false; function getScrollerElement(): HTMLElement | null { const scroller = scrollerRef.value; @@ -1116,6 +1130,30 @@ function getScrollerElement(): HTMLElement | null { return null; } +function scrollGridToTop() { + const scroller = scrollerRef.value; + if (scroller && !(scroller instanceof HTMLElement)) { + scroller.scrollToItem?.(0); + scroller.scrollToPosition?.(0); + } + + const el = getScrollerElement(); + if (el) el.scrollTop = 0; +} + +function resetGridVerticalScroll(afterResult = false) { + if (afterResult) resetScrollAfterResult = true; + if (resetScrollFrame) cancelAnimationFrame(resetScrollFrame); + scrollGridToTop(); + nextTick(() => { + scrollGridToTop(); + resetScrollFrame = requestAnimationFrame(() => { + scrollGridToTop(); + resetScrollFrame = 0; + }); + }); +} + function preserveScrollPosition() { const el = getScrollerElement(); if (!el) return () => {}; @@ -1492,6 +1530,10 @@ function transposeNav(delta: number) { watch( () => props.result, () => { + if (resetScrollAfterResult) { + resetScrollAfterResult = false; + resetGridVerticalScroll(); + } clearCellSelection(); showCellDetail.value = false; detailCell.value = null; @@ -1678,6 +1720,8 @@ function onDdlResizeEnd() { } onUnmounted(() => { + if (resetScrollFrame) cancelAnimationFrame(resetScrollFrame); + if (cancelScrollRestoreFrame) cancelAnimationFrame(cancelScrollRestoreFrame); onDdlResizeEnd(); finishCellSelection(); });