]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): properly handle ssr empty slot and fallback
authorEvan You <yyx990803@gmail.com>
Wed, 30 Dec 2020 20:40:28 +0000 (15:40 -0500)
committerEvan You <yyx990803@gmail.com>
Wed, 30 Dec 2020 20:40:28 +0000 (15:40 -0500)
packages/server-renderer/src/helpers/ssrRenderSlot.ts

index 6231b189525d4e232a2ededce9f2f671849bc02f..5ee6113a198862b3dcfc6fd191087d222c29724c 100644 (file)
@@ -1,5 +1,5 @@
 import { ComponentInternalInstance, Slots } from 'vue'
-import { Props, PushFn, renderVNodeChildren } from '../render'
+import { Props, PushFn, renderVNodeChildren, SSRBufferItem } from '../render'
 
 export type SSRSlots = Record<string, SSRSlot>
 export type SSRSlot = (
@@ -22,18 +22,46 @@ export function ssrRenderSlot(
   const slotFn = slots[slotName]
   if (slotFn) {
     const scopeId = parentComponent && parentComponent.type.__scopeId
+    const slotBuffer: SSRBufferItem[] = []
+    const bufferedPush = (item: SSRBufferItem) => {
+      slotBuffer.push(item)
+    }
     const ret = slotFn(
       slotProps,
-      push,
+      bufferedPush,
       parentComponent,
       scopeId ? ` ${scopeId}-s` : ``
     )
     if (Array.isArray(ret)) {
       // normal slot
       renderVNodeChildren(push, ret, parentComponent)
+    } else {
+      // ssr slot.
+      // check if the slot renders all comments, in which case use the fallback
+      let isEmptySlot = true
+      for (let i = 0; i < slotBuffer.length; i++) {
+        if (!isComment(slotBuffer[i])) {
+          isEmptySlot = false
+          break
+        }
+      }
+      if (isEmptySlot) {
+        if (fallbackRenderFn) {
+          fallbackRenderFn()
+        }
+      } else {
+        for (let i = 0; i < slotBuffer.length; i++) {
+          push(slotBuffer[i])
+        }
+      }
     }
   } else if (fallbackRenderFn) {
     fallbackRenderFn()
   }
   push(`<!--]-->`)
 }
+
+const commentRE = /^<!--.*-->$/
+function isComment(item: SSRBufferItem) {
+  return typeof item === 'string' && commentRE.test(item)
+}