@@ -4,6 +4,7 @@ import { genHandlers } from './events'
44import baseDirectives from '../directives/index'
55import { camelize , no , extend } from 'shared/util'
66import { baseWarn , pluckModuleFunction } from '../helpers'
7+ import { emptySlotScopeToken } from '../parser/index'
78
89type TransformFunction = ( el : ASTElement , code : string ) => string ;
910type DataGenFunction = ( el : ASTElement ) => string ;
@@ -268,7 +269,7 @@ export function genData (el: ASTElement, state: CodegenState): string {
268269 }
269270 // scoped slots
270271 if ( el . scopedSlots ) {
271- data += `${ genScopedSlots ( el . scopedSlots , state ) } ,`
272+ data += `${ genScopedSlots ( el , el . scopedSlots , state ) } ,`
272273 }
273274 // component v-model
274275 if ( el . model ) {
@@ -357,18 +358,36 @@ function genInlineTemplate (el: ASTElement, state: CodegenState): ?string {
357358}
358359
359360function genScopedSlots (
361+ el : ASTElement ,
360362 slots : { [ key : string ] : ASTElement } ,
361363 state : CodegenState
362364) : string {
363- const hasDynamicKeys = Object . keys ( slots ) . some ( key => {
365+ // by default scoped slots are considered "stable", this allows child
366+ // components with only scoped slots to skip forced updates from parent.
367+ // but in some cases we have to bail-out of this optimization
368+ // for example if the slot contains dynamic names, has v-if or v-for on them...
369+ let needsForceUpdate = Object . keys ( slots ) . some ( key => {
364370 const slot = slots [ key ]
365371 return slot . slotTargetDynamic || slot . if || slot . for
366372 } )
373+ // OR when it is inside another scoped slot (the reactivity is disconnected)
374+ // #9438
375+ if ( ! needsForceUpdate ) {
376+ let parent = el . parent
377+ while ( parent ) {
378+ if ( parent . slotScope && parent . slotScope !== emptySlotScopeToken ) {
379+ needsForceUpdate = true
380+ break
381+ }
382+ parent = parent . parent
383+ }
384+ }
385+
367386 return `scopedSlots:_u([${
368387 Object . keys ( slots ) . map ( key => {
369388 return genScopedSlot ( slots [ key ] , state )
370389 } ) . join ( ',' )
371- } ]${ hasDynamicKeys ? `,true` : `` } )`
390+ } ]${ needsForceUpdate ? `,true` : `` } )`
372391}
373392
374393function genScopedSlot (
@@ -382,7 +401,10 @@ function genScopedSlot (
382401 if ( el . for && ! el . forProcessed ) {
383402 return genFor ( el , state , genScopedSlot )
384403 }
385- const fn = `function(${ String ( el . slotScope ) } ){` +
404+ const slotScope = el . slotScope === emptySlotScopeToken
405+ ? ``
406+ : String ( el . slotScope )
407+ const fn = `function(${ slotScope } ){` +
386408 `return ${ el . tag === 'template'
387409 ? el . if && isLegacySyntax
388410 ? `(${ el . if } )?${ genChildren ( el , state ) || 'undefined' } :undefined`
0 commit comments