@@ -12,11 +12,14 @@ import {
12
12
type RootNode ,
13
13
type SimpleExpressionNode ,
14
14
type SlotFunctionExpression ,
15
+ type SlotsObjectProperty ,
15
16
type TemplateChildNode ,
16
17
type TemplateNode ,
17
18
type TextCallNode ,
18
19
type VNodeCall ,
19
20
createArrayExpression ,
21
+ createObjectProperty ,
22
+ createSimpleExpression ,
20
23
getVNodeBlockHelper ,
21
24
getVNodeHelper ,
22
25
} from '../ast'
@@ -140,6 +143,7 @@ function walk(
140
143
}
141
144
142
145
let cachedAsArray = false
146
+ const slotCacheKeys = [ ]
143
147
if ( toCache . length === children . length && node . type === NodeTypes . ELEMENT ) {
144
148
if (
145
149
node . tagType === ElementTypes . ELEMENT &&
@@ -163,6 +167,7 @@ function walk(
163
167
// default slot
164
168
const slot = getSlotNode ( node . codegenNode , 'default' )
165
169
if ( slot ) {
170
+ slotCacheKeys . push ( context . cached . length )
166
171
slot . returns = getCacheExpression (
167
172
createArrayExpression ( slot . returns as TemplateChildNode [ ] ) ,
168
173
)
@@ -186,6 +191,7 @@ function walk(
186
191
slotName . arg &&
187
192
getSlotNode ( parent . codegenNode , slotName . arg )
188
193
if ( slot ) {
194
+ slotCacheKeys . push ( context . cached . length )
189
195
slot . returns = getCacheExpression (
190
196
createArrayExpression ( slot . returns as TemplateChildNode [ ] ) ,
191
197
)
@@ -196,10 +202,31 @@ function walk(
196
202
197
203
if ( ! cachedAsArray ) {
198
204
for ( const child of toCache ) {
205
+ slotCacheKeys . push ( context . cached . length )
199
206
child . codegenNode = context . cache ( child . codegenNode ! )
200
207
}
201
208
}
202
209
210
+ // put the slot cached keys on the slot object, so that the cache
211
+ // can be removed when component unmounting to prevent memory leaks
212
+ if (
213
+ slotCacheKeys . length &&
214
+ node . type === NodeTypes . ELEMENT &&
215
+ node . tagType === ElementTypes . COMPONENT &&
216
+ node . codegenNode &&
217
+ node . codegenNode . type === NodeTypes . VNODE_CALL &&
218
+ node . codegenNode . children &&
219
+ ! isArray ( node . codegenNode . children ) &&
220
+ node . codegenNode . children . type === NodeTypes . JS_OBJECT_EXPRESSION
221
+ ) {
222
+ node . codegenNode . children . properties . push (
223
+ createObjectProperty (
224
+ `__` ,
225
+ createSimpleExpression ( JSON . stringify ( slotCacheKeys ) , false ) ,
226
+ ) as SlotsObjectProperty ,
227
+ )
228
+ }
229
+
203
230
function getCacheExpression ( value : JSChildNode ) : CacheExpression {
204
231
const exp = context . cache ( value )
205
232
// #6978, #7138, #7114
0 commit comments