refactor: fix implementation of SFC :slotted id handling

fix #2892
This commit is contained in:
Evan You
2021-03-05 11:10:06 -05:00
parent cc975c1292
commit aea88c3280
36 changed files with 723 additions and 457 deletions

View File

@@ -6,10 +6,12 @@ export function ssrRenderComponent(
comp: Component,
props: Props | null = null,
children: Slots | SSRSlots | null = null,
parentComponent: ComponentInternalInstance | null = null
parentComponent: ComponentInternalInstance | null = null,
slotScopeId?: string
): SSRBuffer | Promise<SSRBuffer> {
return renderComponentVNode(
createVNode(comp, props, children),
parentComponent
parentComponent,
slotScopeId
)
}

View File

@@ -15,13 +15,13 @@ export function ssrRenderSlot(
slotProps: Props,
fallbackRenderFn: (() => void) | null,
push: PushFn,
parentComponent: ComponentInternalInstance
parentComponent: ComponentInternalInstance,
slotScopeId?: string | null
) {
// template-compiled slots are always rendered as fragments
push(`<!--[-->`)
const slotFn = slots[slotName]
if (slotFn) {
const scopeId = parentComponent && parentComponent.type.__scopeId
const slotBuffer: SSRBufferItem[] = []
const bufferedPush = (item: SSRBufferItem) => {
slotBuffer.push(item)
@@ -30,7 +30,7 @@ export function ssrRenderSlot(
slotProps,
bufferedPush,
parentComponent,
scopeId ? ` ${scopeId}-s` : ``
slotScopeId ? ' ' + slotScopeId : ''
)
if (Array.isArray(ret)) {
// normal slot

View File

@@ -80,7 +80,8 @@ export function createBuffer() {
export function renderComponentVNode(
vnode: VNode,
parentComponent: ComponentInternalInstance | null = null
parentComponent: ComponentInternalInstance | null = null,
slotScopeId?: string
): SSRBuffer | Promise<SSRBuffer> {
const instance = createComponentInstance(vnode, parentComponent, null)
const res = setupComponent(instance, true /* isSSR */)
@@ -97,14 +98,15 @@ export function renderComponentVNode(
warn(`[@vue/server-renderer]: Uncaught error in serverPrefetch:\n`, err)
})
}
return p.then(() => renderComponentSubTree(instance))
return p.then(() => renderComponentSubTree(instance, slotScopeId))
} else {
return renderComponentSubTree(instance)
return renderComponentSubTree(instance, slotScopeId)
}
}
function renderComponentSubTree(
instance: ComponentInternalInstance
instance: ComponentInternalInstance,
slotScopeId?: string
): SSRBuffer | Promise<SSRBuffer> {
const comp = instance.type as Component
const { getBuffer, push } = createBuffer()
@@ -133,13 +135,10 @@ function renderComponentSubTree(
// inherited scopeId
const scopeId = instance.vnode.scopeId
const treeOwnerId = instance.parent && instance.parent.type.__scopeId
const slotScopeId =
treeOwnerId && treeOwnerId !== scopeId ? treeOwnerId + '-s' : null
if (scopeId || slotScopeId) {
attrs = { ...attrs }
if (scopeId) attrs[scopeId] = ''
if (slotScopeId) attrs[slotScopeId] = ''
if (slotScopeId) attrs[slotScopeId.trim()] = ''
}
// set current rendering instance for asset resolution