directives?: Record<string, Directive>
inheritAttrs?: boolean
emits?: (E | EE[]) & ThisType<void>
+ serverPrefetch?(): Promise<any>
// Internal ------------------------------------------------------------------
import { Readable } from 'stream'
import { ssrRenderSlot } from '../src/helpers/ssrRenderSlot'
import { ssrRenderComponent } from '../src/helpers/ssrRenderComponent'
+
const promisifyStream = (stream: Readable) => {
return new Promise((resolve, reject) => {
let result = ''
)
})
})
+
+ test('serverPrefetch', async () => {
+ const msg = Promise.resolve('hello')
+ const app = createApp({
+ data() {
+ return {
+ msg: ''
+ }
+ },
+ async serverPrefetch() {
+ this.msg = await msg
+ },
+ render() {
+ return h('div', this.msg)
+ }
+ })
+ const html = await renderToStream(app)
+ expect(html).toBe(`<div>hello</div>`)
+ })
})
import { renderToString } from '../src/renderToString'
import { ssrRenderSlot, SSRSlot } from '../src/helpers/ssrRenderSlot'
import { ssrRenderComponent } from '../src/helpers/ssrRenderComponent'
+
describe('ssr: renderToString', () => {
test('should apply app context', async () => {
const app = createApp({
).toHaveBeenWarned()
})
})
+
+ test('serverPrefetch', async () => {
+ const msg = Promise.resolve('hello')
+ const app = createApp({
+ data() {
+ return {
+ msg: ''
+ }
+ },
+ async serverPrefetch() {
+ this.msg = await msg
+ },
+ render() {
+ return h('div', this.msg)
+ }
+ })
+ const html = await renderToString(app)
+ expect(html).toBe(`<div>hello</div>`)
+ })
})
Comment,
Component,
ComponentInternalInstance,
+ ComponentOptions,
DirectiveBinding,
Fragment,
mergeProps,
): SSRBuffer | Promise<SSRBuffer> {
const instance = createComponentInstance(vnode, parentComponent, null)
const res = setupComponent(instance, true /* isSSR */)
- if (isPromise(res)) {
- return res
- .catch(err => {
- warn(`[@vue/server-renderer]: Uncaught error in async setup:\n`, err)
+ const hasAsyncSetup = isPromise(res)
+ const prefetch = (vnode.type as ComponentOptions).serverPrefetch
+ if (hasAsyncSetup || prefetch) {
+ let p = hasAsyncSetup
+ ? (res as Promise<void>).catch(err => {
+ warn(`[@vue/server-renderer]: Uncaught error in async setup:\n`, err)
+ })
+ : Promise.resolve()
+ if (prefetch) {
+ p = p.then(() => prefetch.call(instance.proxy)).catch(err => {
+ warn(`[@vue/server-renderer]: Uncaught error in serverPrefetch:\n`, err)
})
- .then(() => renderComponentSubTree(instance))
+ }
+ return p.then(() => renderComponentSubTree(instance))
} else {
return renderComponentSubTree(instance)
}