From 491d5aaa8ab42d8076526501fd2198b004e3438c Mon Sep 17 00:00:00 2001 From: saller Date: Thu, 4 Jul 2024 21:08:55 +0800 Subject: [PATCH] fix(cdk:scroll): virtual list render error after dataSource change (#1949) --- .../src/virtual/composables/useRenderPool.ts | 20 ++++++++++++++++++- .../src/virtual/composables/useScrollState.ts | 16 +++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/cdk/scroll/src/virtual/composables/useRenderPool.ts b/packages/cdk/scroll/src/virtual/composables/useRenderPool.ts index 42f4e4e9e..cbe29bd25 100644 --- a/packages/cdk/scroll/src/virtual/composables/useRenderPool.ts +++ b/packages/cdk/scroll/src/virtual/composables/useRenderPool.ts @@ -143,11 +143,14 @@ export function useRenderPool( updatePoolItem(poolItem, item, index, itemKey) }) + const recycledItems: PoolItem[] = [] + // remove deleted items for (const inactiveKey of inactiveKeys) { const index = items.findIndex(item => item.key === inactiveKey) if (index > -1) { + recycledItems.push(items[index]) items.splice(index, 1) } } @@ -156,6 +159,11 @@ export function useRenderPool( if (updated) { items.sort((item1, item2) => item1.index - item2.index) } + + return { + items, + recycledItems, + } } const updateColPool = (rowPoolItem: RowPoolItem, left: number, right: number, recycleAll: boolean) => { @@ -200,7 +208,17 @@ export function useRenderPool( } const updateRowPool = (top: number, bottom: number, recycleAll: boolean) => { - updatePool(renderedItems.value, rowPool, props.dataSource, top, bottom, recycleAll) + const { recycledItems } = updatePool(renderedItems.value, rowPool, props.dataSource, top, bottom, recycleAll) + + ;(recycledItems as RowPoolItem[]).forEach(item => { + const pool = colPools[item.key] + + if (pool) { + item.cols?.forEach(col => pool.recyclePoolItem(col)) + } + + item.cols = [] + }) if (!props.rowModifier) { return diff --git a/packages/cdk/scroll/src/virtual/composables/useScrollState.ts b/packages/cdk/scroll/src/virtual/composables/useScrollState.ts index d7fb02537..ed9101b51 100644 --- a/packages/cdk/scroll/src/virtual/composables/useScrollState.ts +++ b/packages/cdk/scroll/src/virtual/composables/useScrollState.ts @@ -83,13 +83,17 @@ export function useScrollState( ], ( [enabled, dataSource, bufferSize, rowHeight, colWidth, height, width, getKey, scroll], - [, , , , , oldHeight, oldWidth], + [, oldDataSource, , , , oldHeight, oldWidth], ) => { // to ensure that the rendered size is stable between render cycles // the rendered size should be at least the size of that in last render tick // we do this to maximize render pool reusage let minHorizontalLength: number[] | undefined let minVerticalLength: number | undefined + if (oldDataSource !== dataSource || oldDataSource.length !== dataSource.length) { + calculated = false + } + if (oldWidth === width) { minHorizontalLength = rightIndex.value.map((_rightIndex, index) => _rightIndex - leftIndex.value[index]) } @@ -155,7 +159,7 @@ export function useScrollState( calculated = true } }, - { immediate: true }, + { immediate: true, flush: 'pre' }, ) return { scrollHeight, scrollWidth, scrollOffsetTop, scrollOffsetLeft, topIndex, bottomIndex, leftIndex, rightIndex } @@ -213,7 +217,7 @@ function calcVerticalState( let _renderedHeight = 0 for (let index = 0; index < dataLength; index += 1) { - const rowHeight = getRowHeight(index) + const rowHeight = getRowHeight(getKey(rows[index])) const currentItemBottom = scrollHeight + rowHeight if (currentItemBottom >= scrollTop && topIndex === undefined) { @@ -246,14 +250,14 @@ function calcVerticalState( for (let index = 0; index < bufferSize; index += 1) { if (topIndex !== 0) { topIndex -= 1 - const appendedRowHeight = getRowHeight(topIndex) + const appendedRowHeight = getRowHeight(getKey(rows[topIndex])) offsetTop! -= appendedRowHeight _renderedHeight += appendedRowHeight } if (bottomIndex !== dataLength - 1) { bottomIndex += 1 - _renderedHeight += getRowHeight(bottomIndex) + _renderedHeight += getRowHeight(getKey(rows[bottomIndex])) } } @@ -265,7 +269,7 @@ function calcVerticalState( ) { if (bottomIndex !== dataLength - 1) { bottomIndex += 1 - _renderedHeight += getRowHeight(bottomIndex) + _renderedHeight += getRowHeight(getKey(rows[bottomIndex])) } }