]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(KeepAlive): adapt keepalive for ssr (#3259)
authorHcySunYang <HcySunYang@outlook.com>
Mon, 22 Mar 2021 20:49:07 +0000 (04:49 +0800)
committerGitHub <noreply@github.com>
Mon, 22 Mar 2021 20:49:07 +0000 (16:49 -0400)
fix #3255

packages/runtime-core/src/components/KeepAlive.ts
packages/server-renderer/__tests__/render.spec.ts

index b6d04cbbac36f253800f00d6658cf8df7363138e..cbba10fd755d665e1c7562a029c5fba640f59547 100644 (file)
@@ -77,19 +77,26 @@ const KeepAliveImpl = {
   },
 
   setup(props: KeepAliveProps, { slots }: SetupContext) {
-    const cache: Cache = new Map()
-    const keys: Keys = new Set()
-    let current: VNode | null = null
-
     const instance = getCurrentInstance()!
-    const parentSuspense = instance.suspense
-
     // KeepAlive communicates with the instantiated renderer via the
     // ctx where the renderer passes in its internals,
     // and the KeepAlive instance exposes activate/deactivate implementations.
     // The whole point of this is to avoid importing KeepAlive directly in the
     // renderer to facilitate tree-shaking.
     const sharedContext = instance.ctx as KeepAliveContext
+
+    // if the internal renderer is not registered, it indicates that this is server-side rendering,
+    // for KeepAlive, we just need to render its children
+    if (!sharedContext.renderer) {
+      return slots.default
+    }
+
+    const cache: Cache = new Map()
+    const keys: Keys = new Set()
+    let current: VNode | null = null
+
+    const parentSuspense = instance.suspense
+
     const {
       renderer: {
         p: patch,
index 806ca210b23cdc9381e53f997fd0694c01a73485..37b35f6dea82aacb1d245287a30c0541dc6724bd 100644 (file)
@@ -8,6 +8,7 @@ import {
   defineComponent,
   createTextVNode,
   createStaticVNode,
+  KeepAlive,
   withCtx
 } from 'vue'
 import { escapeHtml } from '@vue/shared'
@@ -604,6 +605,17 @@ function testRender(type: string, render: typeof renderToString) {
       })
     })
 
+    describe('vnode component', () => {
+      test('KeepAlive', async () => {
+        const MyComp = {
+          render: () => h('p', 'hello')
+        }
+        expect(await render(h(KeepAlive, () => h(MyComp)))).toBe(
+          `<!--[--><p>hello</p><!--]-->`
+        )
+      })
+    })
+
     describe('raw vnode types', () => {
       test('Text', async () => {
         expect(await render(createTextVNode('hello <div>'))).toBe(