feat(compiler-ssr): compile portal (#775)
This commit is contained in:
committed by
GitHub
parent
312513d255
commit
d8ed0e7fbf
29
packages/server-renderer/__tests__/ssrRenderPortal.spec.ts
Normal file
29
packages/server-renderer/__tests__/ssrRenderPortal.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { createApp } from 'vue'
|
||||
import { renderToString, SSRContext } from '../src/renderToString'
|
||||
import { ssrRenderPortal } from '../src/helpers/ssrRenderPortal'
|
||||
|
||||
describe('ssrRenderPortal', () => {
|
||||
test('portal rendering', async () => {
|
||||
const ctx = {
|
||||
portals: {}
|
||||
} as SSRContext
|
||||
await renderToString(
|
||||
createApp({
|
||||
data() {
|
||||
return { msg: 'hello' }
|
||||
},
|
||||
ssrRender(_ctx, _push, _parent) {
|
||||
ssrRenderPortal(
|
||||
_push => {
|
||||
_push(`<div>content</div>`)
|
||||
},
|
||||
'#target',
|
||||
_parent
|
||||
)
|
||||
}
|
||||
}),
|
||||
ctx
|
||||
)
|
||||
expect(ctx.portals!['#target']).toBe(`<div>content</div>`)
|
||||
})
|
||||
})
|
||||
20
packages/server-renderer/src/helpers/ssrRenderPortal.ts
Normal file
20
packages/server-renderer/src/helpers/ssrRenderPortal.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { ComponentInternalInstance, ssrContextKey } from 'vue'
|
||||
import { SSRContext, createBuffer, PushFn } from '../renderToString'
|
||||
|
||||
export function ssrRenderPortal(
|
||||
contentRenderFn: (push: PushFn) => void,
|
||||
target: string,
|
||||
parentComponent: ComponentInternalInstance
|
||||
) {
|
||||
const { getBuffer, push } = createBuffer()
|
||||
|
||||
contentRenderFn(push)
|
||||
|
||||
const context = parentComponent.appContext.provides[
|
||||
ssrContextKey as any
|
||||
] as SSRContext
|
||||
const portalBuffers =
|
||||
context.__portalBuffers || (context.__portalBuffers = {})
|
||||
|
||||
portalBuffers[target] = getBuffer()
|
||||
}
|
||||
@@ -13,6 +13,7 @@ export {
|
||||
} from './helpers/ssrRenderAttrs'
|
||||
export { ssrInterpolate } from './helpers/ssrInterpolate'
|
||||
export { ssrRenderList } from './helpers/ssrRenderList'
|
||||
export { ssrRenderPortal } from './helpers/ssrRenderPortal'
|
||||
|
||||
// v-model helpers
|
||||
export {
|
||||
|
||||
@@ -45,9 +45,12 @@ const {
|
||||
// - A resolved buffer (recursive arrays of strings that can be unrolled
|
||||
// synchronously)
|
||||
// - An async buffer (a Promise that resolves to a resolved buffer)
|
||||
type SSRBuffer = SSRBufferItem[]
|
||||
type SSRBufferItem = string | ResolvedSSRBuffer | Promise<ResolvedSSRBuffer>
|
||||
type ResolvedSSRBuffer = (string | ResolvedSSRBuffer)[]
|
||||
export type SSRBuffer = SSRBufferItem[]
|
||||
export type SSRBufferItem =
|
||||
| string
|
||||
| ResolvedSSRBuffer
|
||||
| Promise<ResolvedSSRBuffer>
|
||||
export type ResolvedSSRBuffer = (string | ResolvedSSRBuffer)[]
|
||||
|
||||
export type PushFn = (item: SSRBufferItem) => void
|
||||
|
||||
@@ -62,7 +65,7 @@ export type SSRContext = {
|
||||
>
|
||||
}
|
||||
|
||||
function createBuffer() {
|
||||
export function createBuffer() {
|
||||
let appendable = false
|
||||
let hasAsync = false
|
||||
const buffer: SSRBuffer = []
|
||||
|
||||
Reference in New Issue
Block a user