@@ -12,14 +12,11 @@ import {
1212 type RootNode ,
1313 type SimpleExpressionNode ,
1414 type SlotFunctionExpression ,
15- type SlotsObjectProperty ,
1615 type TemplateChildNode ,
1716 type TemplateNode ,
1817 type TextCallNode ,
1918 type VNodeCall ,
2019 createArrayExpression ,
21- createObjectProperty ,
22- createSimpleExpression ,
2320 getVNodeBlockHelper ,
2421 getVNodeHelper ,
2522} from '../ast'
@@ -70,7 +67,10 @@ function walk(
7067 inFor = false ,
7168) {
7269 const { children } = node
73- const toCache : ( PlainElementNode | TextCallNode ) [ ] = [ ]
70+ const toCacheMap = new Map <
71+ PlainElementNode | TextCallNode ,
72+ undefined | ( ( ) => void )
73+ > ( )
7474 for ( let i = 0 ; i < children . length ; i ++ ) {
7575 const child = children [ i ]
7676 // only plain elements & text calls are eligible for caching.
@@ -83,8 +83,11 @@ function walk(
8383 : getConstantType ( child , context )
8484 if ( constantType > ConstantTypes . NOT_CONSTANT ) {
8585 if ( constantType >= ConstantTypes . CAN_CACHE ) {
86- ; ( child . codegenNode as VNodeCall ) . patchFlag = PatchFlags . CACHED
87- toCache . push ( child )
86+ toCacheMap . set (
87+ child ,
88+ ( ) =>
89+ ( ( child . codegenNode as VNodeCall ) . patchFlag = PatchFlags . CACHED ) ,
90+ )
8891 continue
8992 }
9093 } else {
@@ -115,16 +118,17 @@ function walk(
115118 ? ConstantTypes . NOT_CONSTANT
116119 : getConstantType ( child , context )
117120 if ( constantType >= ConstantTypes . CAN_CACHE ) {
118- if (
119- child . codegenNode . type === NodeTypes . JS_CALL_EXPRESSION &&
120- child . codegenNode . arguments . length > 0
121- ) {
122- child . codegenNode . arguments . push (
123- PatchFlags . CACHED +
124- ( __DEV__ ? ` /* ${ PatchFlagNames [ PatchFlags . CACHED ] } */` : `` ) ,
125- )
126- }
127- toCache . push ( child )
121+ toCacheMap . set ( child , ( ) => {
122+ if (
123+ child . codegenNode . type === NodeTypes . JS_CALL_EXPRESSION &&
124+ child . codegenNode . arguments . length > 0
125+ ) {
126+ child . codegenNode . arguments . push (
127+ PatchFlags . CACHED +
128+ ( __DEV__ ? ` /* ${ PatchFlagNames [ PatchFlags . CACHED ] } */` : `` ) ,
129+ )
130+ }
131+ } )
128132 continue
129133 }
130134 }
@@ -157,8 +161,7 @@ function walk(
157161 }
158162
159163 let cachedAsArray = false
160- const slotCacheKeys = [ ]
161- if ( toCache . length === children . length && node . type === NodeTypes . ELEMENT ) {
164+ if ( toCacheMap . size === children . length && node . type === NodeTypes . ELEMENT ) {
162165 if (
163166 node . tagType === ElementTypes . ELEMENT &&
164167 node . codegenNode &&
@@ -181,7 +184,6 @@ function walk(
181184 // default slot
182185 const slot = getSlotNode ( node . codegenNode , 'default' )
183186 if ( slot ) {
184- slotCacheKeys . push ( context . cached . length )
185187 slot . returns = getCacheExpression (
186188 createArrayExpression ( slot . returns as TemplateChildNode [ ] ) ,
187189 )
@@ -205,7 +207,6 @@ function walk(
205207 slotName . arg &&
206208 getSlotNode ( parent . codegenNode , slotName . arg )
207209 if ( slot ) {
208- slotCacheKeys . push ( context . cached . length )
209210 slot . returns = getCacheExpression (
210211 createArrayExpression ( slot . returns as TemplateChildNode [ ] ) ,
211212 )
@@ -215,40 +216,24 @@ function walk(
215216 }
216217
217218 if ( ! cachedAsArray ) {
218- for ( const child of toCache ) {
219- slotCacheKeys . push ( context . cached . length )
219+ for ( const [ child , setupCache ] of toCacheMap ) {
220+ if ( setupCache ) setupCache ( )
220221 child . codegenNode = context . cache ( child . codegenNode ! )
221222 }
222223 }
223224
224- // put the slot cached keys on the slot object, so that the cache
225- // can be removed when component unmounting to prevent memory leaks
226- if (
227- slotCacheKeys . length &&
228- node . type === NodeTypes . ELEMENT &&
229- node . tagType === ElementTypes . COMPONENT &&
230- node . codegenNode &&
231- node . codegenNode . type === NodeTypes . VNODE_CALL &&
232- node . codegenNode . children &&
233- ! isArray ( node . codegenNode . children ) &&
234- node . codegenNode . children . type === NodeTypes . JS_OBJECT_EXPRESSION
235- ) {
236- node . codegenNode . children . properties . push (
237- createObjectProperty (
238- `__` ,
239- createSimpleExpression ( JSON . stringify ( slotCacheKeys ) , false ) ,
240- ) as SlotsObjectProperty ,
241- )
242- }
243-
244- function getCacheExpression ( value : JSChildNode ) : CacheExpression {
225+ function getCacheExpression (
226+ value : JSChildNode ,
227+ cachedAsArray : boolean = true ,
228+ ) : CacheExpression {
245229 const exp = context . cache ( value )
246230 // #6978, #7138, #7114
247231 // a cached children array inside v-for can caused HMR errors since
248232 // it might be mutated when mounting the first item
249233 if ( inFor && context . hmr ) {
250234 exp . needArraySpread = true
251235 }
236+ exp . cachedAsArray = cachedAsArray
252237 return exp
253238 }
254239
@@ -268,7 +253,7 @@ function walk(
268253 }
269254 }
270255
271- if ( toCache . length && context . transformHoist ) {
256+ if ( toCacheMap . size && context . transformHoist ) {
272257 context . transformHoist ( children , context , node )
273258 }
274259}
0 commit comments