feat(ssr/suspense): suspense hydration

In order to support hydration of async components, server-rendered
fragments must be explicitly marked with comment nodes.
This commit is contained in:
Evan You
2020-03-12 22:19:41 -04:00
parent b3d7d64931
commit a3cc970030
19 changed files with 385 additions and 139 deletions

View File

@@ -18,6 +18,8 @@ export function ssrRenderSlot(
push: PushFn,
parentComponent: ComponentInternalInstance
) {
// template-compiled slots are always rendered as fragments
push(`<!--1-->`)
const slotFn = slots[slotName]
if (slotFn) {
if (slotFn.length > 1) {
@@ -31,4 +33,5 @@ export function ssrRenderSlot(
} else if (fallbackRenderFn) {
fallbackRenderFn()
}
push(`<!--0-->`)
}

View File

@@ -1,19 +1,30 @@
import { PushFn, ResolvedSSRBuffer, createBuffer } from '../renderToString'
import { NOOP } from '@vue/shared'
type ContentRenderFn = (push: PushFn) => void
export async function ssrRenderSuspense({
default: renderContent = NOOP,
fallback: renderFallback = NOOP
default: renderContent,
fallback: renderFallback
}: Record<string, ContentRenderFn | undefined>): Promise<ResolvedSSRBuffer> {
try {
const { push, getBuffer } = createBuffer()
renderContent(push)
return await getBuffer()
if (renderContent) {
const { push, getBuffer } = createBuffer()
push(`<!--1-->`)
renderContent(push)
push(`<!--0-->`)
return await getBuffer()
} else {
return []
}
} catch {
const { push, getBuffer } = createBuffer()
renderFallback(push)
return getBuffer()
if (renderFallback) {
const { push, getBuffer } = createBuffer()
push(`<!--1-->`)
renderFallback(push)
push(`<!--0-->`)
return getBuffer()
} else {
return []
}
}
}