File tree 3 files changed +55
-5
lines changed
test/unit/features/component
3 files changed +55
-5
lines changed Original file line number Diff line number Diff line change @@ -78,9 +78,13 @@ export function renderMixin (Vue: Class<Component>) {
78
78
} = vm . $options
79
79
80
80
if ( vm . _isMounted ) {
81
- // clone slot nodes on re-renders
81
+ // if the parent didn't update, the slot nodes will be the ones from
82
+ // last render. They need to be cloned to ensure "freshness" for this render.
82
83
for ( const key in vm . $slots ) {
83
- vm . $slots [ key ] = cloneVNodes ( vm . $slots [ key ] )
84
+ const slot = vm . $slots [ key ]
85
+ if ( slot . _rendered ) {
86
+ vm . $slots [ key ] = cloneVNodes ( slot , true /* deep */ )
87
+ }
84
88
}
85
89
}
86
90
Original file line number Diff line number Diff line change @@ -79,7 +79,7 @@ export function createTextVNode (val: string | number) {
79
79
// used for static nodes and slot nodes because they may be reused across
80
80
// multiple renders, cloning them avoids errors when DOM manipulations rely
81
81
// on their elm reference.
82
- export function cloneVNode ( vnode : VNode ) : VNode {
82
+ export function cloneVNode ( vnode : VNode , deep ?: boolean ) : VNode {
83
83
const cloned = new VNode (
84
84
vnode . tag ,
85
85
vnode . data ,
@@ -95,14 +95,17 @@ export function cloneVNode (vnode: VNode): VNode {
95
95
cloned . key = vnode . key
96
96
cloned . isComment = vnode . isComment
97
97
cloned . isCloned = true
98
+ if ( deep ) {
99
+ cloned . children = vnode . children && cloneVNodes ( vnode . children )
100
+ }
98
101
return cloned
99
102
}
100
103
101
- export function cloneVNodes ( vnodes : Array < VNode > ) : Array < VNode > {
104
+ export function cloneVNodes ( vnodes : Array < VNode > , deep ?: boolean ) : Array < VNode > {
102
105
const len = vnodes . length
103
106
const res = new Array ( len )
104
107
for ( let i = 0 ; i < len ; i ++ ) {
105
- res [ i ] = cloneVNode ( vnodes [ i ] )
108
+ res [ i ] = cloneVNode ( vnodes [ i ] , deep )
106
109
}
107
110
return res
108
111
}
Original file line number Diff line number Diff line change @@ -685,4 +685,47 @@ describe('Component slot', () => {
685
685
} ) . $mount ( )
686
686
expect ( vm . $el . innerHTML ) . toBe ( '<div>default<span>foo</span></div>' )
687
687
} )
688
+
689
+ it ( 'should handle nested components in slots properly' , done => {
690
+ const TestComponent = {
691
+ template : `
692
+ <component :is="toggleEl ? 'b' : 'i'">
693
+ <slot />
694
+ </component>
695
+ ` ,
696
+ data ( ) {
697
+ return {
698
+ toggleEl : true
699
+ }
700
+ }
701
+ }
702
+
703
+ const vm = new Vue ( {
704
+ template : `
705
+ <div>
706
+ <test-component ref="test">
707
+ <div>
708
+ <foo/>
709
+ </div><bar/>
710
+ </test-component>
711
+ </div>
712
+ ` ,
713
+ components : {
714
+ TestComponent,
715
+ foo : {
716
+ template : `<div>foo</div>`
717
+ } ,
718
+ bar : {
719
+ template : `<div>bar</div>`
720
+ }
721
+ }
722
+ } ) . $mount ( )
723
+
724
+ expect ( vm . $el . innerHTML ) . toBe ( `<b><div><div>foo</div></div><div>bar</div></b>` )
725
+
726
+ vm . $refs . test . toggleEl = false
727
+ waitForUpdate ( ( ) => {
728
+ expect ( vm . $el . innerHTML ) . toBe ( `<i><div><div>foo</div></div><div>bar</div></i>` )
729
+ } ) . then ( done )
730
+ } )
688
731
} )
You can’t perform that action at this time.
0 commit comments