@@ -45,51 +45,93 @@ export function initSlots(
4545 // with ctx
4646 const slots = rawSlots [ 0 ] as StaticSlots
4747 for ( const name in slots ) {
48- registerSlot ( name , slots [ name ] )
48+ resolveSlot ( name , slots [ name ] )
4949 }
5050 return
5151 }
5252
5353 instance . slots = shallowReactive ( { } )
54- const keys : Set < string > [ ] = [ ]
54+ const renderedSlotKeys : Set < string > [ ] = [ ]
55+ const slotNameLevels : Record < string , [ number , Slot ] [ ] > = { }
5556 rawSlots . forEach ( ( slots , index ) => {
5657 const isDynamicSlot = isDynamicSlotFn ( slots )
5758 if ( isDynamicSlot ) {
5859 firstEffect ( instance , ( ) => {
59- const recordNames = keys [ index ] || ( keys [ index ] = new Set ( ) )
60+ const renderedKeys =
61+ renderedSlotKeys [ index ] || ( renderedSlotKeys [ index ] = new Set ( ) )
6062 let dynamicSlot : ReturnType < DynamicSlotFn >
61- if ( isDynamicSlotFn ( slots ) ) {
62- dynamicSlot = slots ( )
63- if ( isArray ( dynamicSlot ) ) {
64- for ( const slot of dynamicSlot ) {
65- registerSlot ( slot . name , slot . fn , recordNames )
66- }
67- } else if ( dynamicSlot ) {
68- registerSlot ( dynamicSlot . name , dynamicSlot . fn , recordNames )
63+ dynamicSlot = slots ( )
64+ const restoreKeys = cleanupSlot ( index )
65+ if ( isArray ( dynamicSlot ) ) {
66+ for ( const slot of dynamicSlot ) {
67+ registerSlot ( slot . name , slot . fn , index , renderedKeys )
68+ }
69+ } else if ( dynamicSlot ) {
70+ registerSlot ( dynamicSlot . name , dynamicSlot . fn , index , renderedKeys )
71+ }
72+ if ( restoreKeys . length ) {
73+ for ( const key of restoreKeys ) {
74+ resolveSlot ( key , slotNameLevels [ key ] [ 0 ] [ 1 ] )
6975 }
70- } else {
7176 }
72- for ( const name of recordNames ) {
77+ for ( const name of renderedKeys ) {
7378 if (
7479 ! ( isArray ( dynamicSlot )
7580 ? dynamicSlot . some ( s => s . name === name )
7681 : dynamicSlot && dynamicSlot . name === name )
7782 ) {
78- recordNames . delete ( name )
83+ renderedKeys . delete ( name )
7984 delete instance . slots [ name ]
8085 }
8186 }
8287 } )
8388 } else {
8489 for ( const name in slots ) {
85- registerSlot ( name , slots [ name ] )
90+ registerSlot ( name , slots [ name ] , index )
8691 }
8792 }
8893 } )
8994
90- function registerSlot ( name : string , fn : Slot , recordNames ?: Set < string > ) {
95+ function cleanupSlot ( level : number ) {
96+ const restoreKeys : string [ ] = [ ]
97+ Object . keys ( slotNameLevels ) . forEach ( key => {
98+ const index = slotNameLevels [ key ] . findIndex ( ( [ l ] ) => l === level )
99+ if ( index > - 1 ) {
100+ slotNameLevels [ key ] . splice ( index , 1 )
101+ if ( ! slotNameLevels [ key ] . length ) {
102+ delete slotNameLevels [ key ]
103+ return
104+ }
105+ if ( index === 0 ) {
106+ renderedSlotKeys [ level ] && renderedSlotKeys [ level ] . delete ( key )
107+ restoreKeys . push ( key )
108+ }
109+ }
110+ } )
111+ return restoreKeys
112+ }
113+
114+ function registerSlot (
115+ name : string ,
116+ fn : Slot ,
117+ level : number ,
118+ renderedKeys ?: Set < string > ,
119+ ) {
120+ slotNameLevels [ name ] = slotNameLevels [ name ] || [ ]
121+ slotNameLevels [ name ] . push ( [ level , fn ] )
122+ slotNameLevels [ name ] . sort ( ( a , b ) => b [ 0 ] - a [ 0 ] )
123+ for ( let i = 1 ; i < slotNameLevels [ name ] . length ; i ++ ) {
124+ const hidenLevel = slotNameLevels [ name ] [ i ] [ 0 ]
125+ renderedSlotKeys [ hidenLevel ] && renderedSlotKeys [ hidenLevel ] . delete ( name )
126+ }
127+ if ( slotNameLevels [ name ] [ 0 ] [ 0 ] === level ) {
128+ renderedKeys && renderedKeys . add ( name )
129+ }
130+ resolveSlot ( name , slotNameLevels [ name ] [ 0 ] [ 1 ] )
131+ }
132+
133+ function resolveSlot ( name : string , fn : Slot ) {
91134 instance . slots [ name ] = withCtx ( fn )
92- recordNames && recordNames . add ( name )
93135 }
94136
95137 function withCtx ( fn : Slot ) : Slot {
0 commit comments