From: edison Date: Wed, 7 Aug 2024 03:24:17 +0000 (+0800) Subject: fix(keep-alive): avoid cache suspense comment root (#11479) X-Git-Tag: v3.4.37~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a917c0539cdc55c0188ca91f70b6ff79fee13ed9;p=thirdparty%2Fvuejs%2Fcore.git fix(keep-alive): avoid cache suspense comment root (#11479) --- diff --git a/packages/runtime-core/__tests__/components/Suspense.spec.ts b/packages/runtime-core/__tests__/components/Suspense.spec.ts index 8de5b3182d..62765dad98 100644 --- a/packages/runtime-core/__tests__/components/Suspense.spec.ts +++ b/packages/runtime-core/__tests__/components/Suspense.spec.ts @@ -8,6 +8,7 @@ import { KeepAlive, Suspense, type SuspenseProps, + createCommentVNode, h, nextTick, nodeOps, @@ -2085,6 +2086,35 @@ describe('Suspense', () => { expect(serializeInner(root)).toBe(`
async2
`) }) + test('KeepAlive + Suspense + comment slot', async () => { + const toggle = ref(false) + const Async = defineAsyncComponent({ + render() { + return h('div', 'async1') + }, + }) + const App = { + render() { + return h(KeepAlive, null, { + default: () => { + return h(Suspense, null, { + default: toggle.value ? h(Async) : createCommentVNode('v-if'), + }) + }, + }) + }, + } + + const root = nodeOps.createElement('div') + render(h(App), root) + expect(serializeInner(root)).toBe(``) + + toggle.value = true + await nextTick() + await Promise.all(deps) + expect(serializeInner(root)).toBe(`
async1
`) + }) + // #6416 follow up / #10017 test('Suspense patched during HOC async component re-mount', async () => { const key = ref('k') diff --git a/packages/runtime-core/src/components/KeepAlive.ts b/packages/runtime-core/src/components/KeepAlive.ts index a2c8c2bf1a..74cb1b1c12 100644 --- a/packages/runtime-core/src/components/KeepAlive.ts +++ b/packages/runtime-core/src/components/KeepAlive.ts @@ -8,6 +8,7 @@ import { getCurrentInstance, } from '../component' import { + Comment, type VNode, type VNodeProps, cloneVNode, @@ -287,6 +288,12 @@ const KeepAliveImpl: ComponentOptions = { } let vnode = getInnerChild(rawVNode) + // #6028 Suspense ssContent maybe a comment VNode, should avoid caching it + if (vnode.type === Comment) { + current = null + return vnode + } + const comp = vnode.type as ConcreteComponent // for async components, name check should be based in its loaded