@@ -111,7 +111,8 @@ function renderComponentSubTree(
111
111
renderVNode (
112
112
push ,
113
113
( instance . subTree = renderComponentRoot ( instance ) ) ,
114
- instance
114
+ instance ,
115
+ slotScopeId
115
116
)
116
117
} else {
117
118
if (
@@ -174,7 +175,8 @@ function renderComponentSubTree(
174
175
renderVNode (
175
176
push ,
176
177
( instance . subTree = renderComponentRoot ( instance ) ) ,
177
- instance
178
+ instance ,
179
+ slotScopeId
178
180
)
179
181
} else {
180
182
warn (
@@ -191,7 +193,8 @@ function renderComponentSubTree(
191
193
export function renderVNode (
192
194
push : PushFn ,
193
195
vnode : VNode ,
194
- parentComponent : ComponentInternalInstance
196
+ parentComponent : ComponentInternalInstance ,
197
+ slotScopeId ?: string
195
198
) {
196
199
const { type, shapeFlag, children } = vnode
197
200
switch ( type ) {
@@ -207,19 +210,28 @@ export function renderVNode(
207
210
push ( children as string )
208
211
break
209
212
case Fragment :
213
+ if ( vnode . slotScopeIds ) {
214
+ slotScopeId =
215
+ ( slotScopeId ? slotScopeId + ' ' : '' ) + vnode . slotScopeIds . join ( ' ' )
216
+ }
210
217
push ( `<!--[-->` ) // open
211
- renderVNodeChildren ( push , children as VNodeArrayChildren , parentComponent )
218
+ renderVNodeChildren (
219
+ push ,
220
+ children as VNodeArrayChildren ,
221
+ parentComponent ,
222
+ slotScopeId
223
+ )
212
224
push ( `<!--]-->` ) // close
213
225
break
214
226
default :
215
227
if ( shapeFlag & ShapeFlags . ELEMENT ) {
216
- renderElementVNode ( push , vnode , parentComponent )
228
+ renderElementVNode ( push , vnode , parentComponent , slotScopeId )
217
229
} else if ( shapeFlag & ShapeFlags . COMPONENT ) {
218
- push ( renderComponentVNode ( vnode , parentComponent ) )
230
+ push ( renderComponentVNode ( vnode , parentComponent , slotScopeId ) )
219
231
} else if ( shapeFlag & ShapeFlags . TELEPORT ) {
220
- renderTeleportVNode ( push , vnode , parentComponent )
232
+ renderTeleportVNode ( push , vnode , parentComponent , slotScopeId )
221
233
} else if ( shapeFlag & ShapeFlags . SUSPENSE ) {
222
- renderVNode ( push , vnode . ssContent ! , parentComponent )
234
+ renderVNode ( push , vnode . ssContent ! , parentComponent , slotScopeId )
223
235
} else {
224
236
warn (
225
237
'[@vue/server-renderer] Invalid VNode type:' ,
@@ -233,17 +245,19 @@ export function renderVNode(
233
245
export function renderVNodeChildren (
234
246
push : PushFn ,
235
247
children : VNodeArrayChildren ,
236
- parentComponent : ComponentInternalInstance
248
+ parentComponent : ComponentInternalInstance ,
249
+ slotScopeId : string | undefined
237
250
) {
238
251
for ( let i = 0 ; i < children . length ; i ++ ) {
239
- renderVNode ( push , normalizeVNode ( children [ i ] ) , parentComponent )
252
+ renderVNode ( push , normalizeVNode ( children [ i ] ) , parentComponent , slotScopeId )
240
253
}
241
254
}
242
255
243
256
function renderElementVNode (
244
257
push : PushFn ,
245
258
vnode : VNode ,
246
- parentComponent : ComponentInternalInstance
259
+ parentComponent : ComponentInternalInstance ,
260
+ slotScopeId : string | undefined
247
261
) {
248
262
const tag = vnode . type as string
249
263
let { props, children, shapeFlag, scopeId, dirs } = vnode
@@ -257,7 +271,22 @@ function renderElementVNode(
257
271
openTag += ssrRenderAttrs ( props , tag )
258
272
}
259
273
260
- openTag += resolveScopeId ( scopeId , vnode , parentComponent )
274
+ if ( scopeId ) {
275
+ openTag += ` ${ scopeId } `
276
+ }
277
+ // inherit parent chain scope id if this is the root node
278
+ let curParent : ComponentInternalInstance | null = parentComponent
279
+ let curVnode = vnode
280
+ while ( curParent && curVnode === curParent . subTree ) {
281
+ curVnode = curParent . vnode
282
+ if ( curVnode . scopeId ) {
283
+ openTag += ` ${ curVnode . scopeId } `
284
+ }
285
+ curParent = curParent . parent
286
+ }
287
+ if ( slotScopeId ) {
288
+ openTag += ` ${ slotScopeId } `
289
+ }
261
290
262
291
push ( openTag + `>` )
263
292
if ( ! isVoidTag ( tag ) ) {
@@ -281,41 +310,15 @@ function renderElementVNode(
281
310
renderVNodeChildren (
282
311
push ,
283
312
children as VNodeArrayChildren ,
284
- parentComponent
313
+ parentComponent ,
314
+ slotScopeId
285
315
)
286
316
}
287
317
}
288
318
push ( `</${ tag } >` )
289
319
}
290
320
}
291
321
292
- function resolveScopeId (
293
- scopeId : string | null ,
294
- vnode : VNode ,
295
- parentComponent : ComponentInternalInstance | null
296
- ) {
297
- let res = ``
298
- if ( scopeId ) {
299
- res = ` ${ scopeId } `
300
- }
301
- if ( parentComponent ) {
302
- const treeOwnerId = parentComponent . type . __scopeId
303
- // vnode's own scopeId and the current rendering component's scopeId is
304
- // different - this is a slot content node.
305
- if ( treeOwnerId && treeOwnerId !== scopeId ) {
306
- res += ` ${ treeOwnerId } -s`
307
- }
308
- if ( vnode === parentComponent . subTree ) {
309
- res += resolveScopeId (
310
- parentComponent . vnode . scopeId ,
311
- parentComponent . vnode ,
312
- parentComponent . parent
313
- )
314
- }
315
- }
316
- return res
317
- }
318
-
319
322
function applySSRDirectives (
320
323
vnode : VNode ,
321
324
rawProps : VNodeProps | null ,
@@ -338,7 +341,8 @@ function applySSRDirectives(
338
341
function renderTeleportVNode (
339
342
push : PushFn ,
340
343
vnode : VNode ,
341
- parentComponent : ComponentInternalInstance
344
+ parentComponent : ComponentInternalInstance ,
345
+ slotScopeId : string | undefined
342
346
) {
343
347
const target = vnode . props && vnode . props . to
344
348
const disabled = vnode . props && vnode . props . disabled
@@ -358,7 +362,8 @@ function renderTeleportVNode(
358
362
renderVNodeChildren (
359
363
push ,
360
364
vnode . children as VNodeArrayChildren ,
361
- parentComponent
365
+ parentComponent ,
366
+ slotScopeId
362
367
)
363
368
} ,
364
369
target ,
0 commit comments