From edf263847eddc910f4d2de68287d84b8c66c3860 Mon Sep 17 00:00:00 2001 From: edison Date: Fri, 7 Jun 2024 17:29:28 +0800 Subject: [PATCH] fix(runtime-core): fix stale v-memo after v-if toggle (#6606) close #6593 --- .../runtime-core/__tests__/helpers/withMemo.spec.ts | 11 +++++++++++ packages/runtime-core/src/component.ts | 2 +- packages/runtime-core/src/helpers/withMemo.ts | 2 ++ packages/runtime-core/src/renderer.ts | 6 ++++++ packages/runtime-core/src/vnode.ts | 4 ++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/helpers/withMemo.spec.ts b/packages/runtime-core/__tests__/helpers/withMemo.spec.ts index f4f356dea4f..32f89b1d8e9 100644 --- a/packages/runtime-core/__tests__/helpers/withMemo.spec.ts +++ b/packages/runtime-core/__tests__/helpers/withMemo.spec.ts @@ -148,6 +148,17 @@ describe('v-memo', () => { // should update await nextTick() expect(el.innerHTML).toBe(`
3 3
`) + + vm.ok = true + await nextTick() + vm.ok = false + await nextTick() + expect(el.innerHTML).toBe(`
3 3
`) + + vm.y++ + // should update + await nextTick() + expect(el.innerHTML).toBe(`
4 3
`) }) test('on v-for', async () => { diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index f2ca0464142..70a3716a3e3 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -322,7 +322,7 @@ export interface ComponentInternalInstance { * after initialized (e.g. inline handlers) * @internal */ - renderCache: (Function | VNode)[] + renderCache: (Function | VNode | undefined)[] /** * Resolved component registry, only for components with mixins or extends diff --git a/packages/runtime-core/src/helpers/withMemo.ts b/packages/runtime-core/src/helpers/withMemo.ts index 97fbad31fb9..72ef814eefa 100644 --- a/packages/runtime-core/src/helpers/withMemo.ts +++ b/packages/runtime-core/src/helpers/withMemo.ts @@ -15,6 +15,8 @@ export function withMemo( // shallow clone ret.memo = memo.slice() + ret.memoIndex = index + return (cache[index] = ret) } diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index d06c6858415..2a35a5e1925 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -2110,12 +2110,18 @@ function baseCreateRenderer( shapeFlag, patchFlag, dirs, + memoIndex, } = vnode // unset ref if (ref != null) { setRef(ref, null, parentSuspense, vnode, true) } + // #6593 should clean memo cache when unmount + if (memoIndex != null) { + parentComponent!.renderCache[memoIndex] = undefined + } + if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) { ;(parentComponent!.ctx as KeepAliveContext).deactivate(vnode) return diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index 617bdf7ad58..7abd45c7fa5 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -228,6 +228,10 @@ export interface VNode< * @internal attached by v-memo */ memo?: any[] + /** + * @internal index for cleaning v-memo cache + */ + memoIndex?: number /** * @internal __COMPAT__ only */