diff --git a/packages/runtime-vapor/__tests__/for.spec.ts b/packages/runtime-vapor/__tests__/for.spec.ts index 5c71de8c2..572c8af85 100644 --- a/packages/runtime-vapor/__tests__/for.spec.ts +++ b/packages/runtime-vapor/__tests__/for.spec.ts @@ -940,7 +940,7 @@ describe('createFor', () => { ) }) - test.todo('remove from beginning and insert at end', async () => { + test('remove from beginning and insert at end', async () => { const arr = ref([1, 2, 3]) const { host, html } = render(arr) expect(host.children.length).toBe(3) @@ -1028,7 +1028,7 @@ describe('createFor', () => { ) }) - test.todo('move to left & replace', async () => { + test('move to left & replace', async () => { const arr = ref([1, 2, 3, 4, 5]) const { host, html } = render(arr) expect(host.children.length).toBe(5) @@ -1044,7 +1044,7 @@ describe('createFor', () => { ) }) - test.todo('move to left and leaves hold', async () => { + test('move to left and leaves hold', async () => { const arr = ref([1, 4, 5]) const { host, html } = render(arr) expect(host.children.length).toBe(3) @@ -1058,24 +1058,21 @@ describe('createFor', () => { expect(html()).toBe(`46`) }) - test.todo( - 'moved and set to undefined element ending at the end', - async () => { - const arr = ref([2, 4, 5]) - const { host, html } = render(arr) - expect(host.children.length).toBe(3) - expect(html()).toBe( - `245`, - ) + test('moved and set to undefined element ending at the end', async () => { + const arr = ref([2, 4, 5]) + const { host, html } = render(arr) + expect(host.children.length).toBe(3) + expect(html()).toBe( + `245`, + ) - arr.value = [4, 5, 3] - await nextTick() - expect(host.children.length).toBe(3) - expect(html()).toBe( - `453`, - ) - }, - ) + arr.value = [4, 5, 3] + await nextTick() + expect(host.children.length).toBe(3) + expect(html()).toBe( + `453`, + ) + }) test('reverse element', async () => { const arr = ref([1, 2, 3, 4, 5, 6, 7, 8]) @@ -1323,7 +1320,7 @@ describe('createFor', () => { }).render() } - test.todo('move a key in non-keyed nodes with a size up', async () => { + test('move a key in non-keyed nodes with a size up', async () => { const arr = ref([1, 'a', 'b', 'c']) const { host, html } = define({ setup() { diff --git a/packages/runtime-vapor/src/apiCreateFor.ts b/packages/runtime-vapor/src/apiCreateFor.ts index af303a638..5c868a5a7 100644 --- a/packages/runtime-vapor/src/apiCreateFor.ts +++ b/packages/runtime-vapor/src/apiCreateFor.ts @@ -254,6 +254,7 @@ export const createFor = ( previousKeyIndexPairs.length = previousKeyIndexInsertIndex const previousKeyIndexMap = new Map(previousKeyIndexPairs) + const blocksToMove: (() => void)[] = [] const blocksToMount: [ blockIndex: number, blockItem: ReturnType, @@ -272,13 +273,15 @@ export const createFor = ( const reusedBlock = (newBlocks[blockIndex] = oldBlocks[previousIndex]) update(reusedBlock, ...blockItem) - insert( - reusedBlock, - parent!, - anchorOffset === -1 - ? anchorFallback - : normalizeAnchor(newBlocks[anchorOffset].nodes), - ) + blocksToMove.push(() => { + insert( + reusedBlock, + parent!, + anchorOffset === -1 + ? anchorFallback + : normalizeAnchor(newBlocks[anchorOffset].nodes), + ) + }) previousKeyIndexMap.delete(blockKey) } else { blocksToMount.push([ @@ -341,6 +344,16 @@ export const createFor = ( blockKey, ) } + + if (blocksToMove.length > 0) { + // update anchorFallback to the last block if any new mounted blocks used it + if (blocksToMount.some(move => move[3] === -1)) { + anchorFallback = normalizeAnchor( + newBlocks[newBlocks.length - 1].nodes, + ) + } + blocksToMove.forEach(move => move()) + } } } }