@@ -45,51 +45,93 @@ export function initSlots(
45
45
// with ctx
46
46
const slots = rawSlots [ 0 ] as StaticSlots
47
47
for ( const name in slots ) {
48
- registerSlot ( name , slots [ name ] )
48
+ resolveSlot ( name , slots [ name ] )
49
49
}
50
50
return
51
51
}
52
52
53
53
instance . slots = shallowReactive ( { } )
54
- const keys : Set < string > [ ] = [ ]
54
+ const renderedSlotKeys : Set < string > [ ] = [ ]
55
+ const slotNameLevels : Record < string , [ number , Slot ] [ ] > = { }
55
56
rawSlots . forEach ( ( slots , index ) => {
56
57
const isDynamicSlot = isDynamicSlotFn ( slots )
57
58
if ( isDynamicSlot ) {
58
59
firstEffect ( instance , ( ) => {
59
- const recordNames = keys [ index ] || ( keys [ index ] = new Set ( ) )
60
+ const renderedKeys =
61
+ renderedSlotKeys [ index ] || ( renderedSlotKeys [ index ] = new Set ( ) )
60
62
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 ] )
69
75
}
70
- } else {
71
76
}
72
- for ( const name of recordNames ) {
77
+ for ( const name of renderedKeys ) {
73
78
if (
74
79
! ( isArray ( dynamicSlot )
75
80
? dynamicSlot . some ( s => s . name === name )
76
81
: dynamicSlot && dynamicSlot . name === name )
77
82
) {
78
- recordNames . delete ( name )
83
+ renderedKeys . delete ( name )
79
84
delete instance . slots [ name ]
80
85
}
81
86
}
82
87
} )
83
88
} else {
84
89
for ( const name in slots ) {
85
- registerSlot ( name , slots [ name ] )
90
+ registerSlot ( name , slots [ name ] , index )
86
91
}
87
92
}
88
93
} )
89
94
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 ) {
91
134
instance . slots [ name ] = withCtx ( fn )
92
- recordNames && recordNames . add ( name )
93
135
}
94
136
95
137
function withCtx ( fn : Slot ) : Slot {
0 commit comments