Skip to content

Commit 740951f

Browse files
committed
fix(compiler-core): remove slot cache from parent renderCache during unmounting
1 parent 4f79253 commit 740951f

File tree

5 files changed

+58
-3
lines changed

5 files changed

+58
-3
lines changed

packages/compiler-core/__tests__/transforms/cacheStatic.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ describe('compiler: cacheStatic transform', () => {
170170
{
171171
/* _ slot flag */
172172
},
173+
{
174+
type: NodeTypes.JS_PROPERTY,
175+
key: { content: '__' },
176+
value: { content: '[0]' },
177+
},
173178
],
174179
})
175180
})
@@ -197,6 +202,11 @@ describe('compiler: cacheStatic transform', () => {
197202
{
198203
/* _ slot flag */
199204
},
205+
{
206+
type: NodeTypes.JS_PROPERTY,
207+
key: { content: '__' },
208+
value: { content: '[0]' },
209+
},
200210
],
201211
})
202212
})

packages/compiler-core/src/transforms/cacheStatic.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ import {
1212
type RootNode,
1313
type SimpleExpressionNode,
1414
type SlotFunctionExpression,
15+
type SlotsObjectExpression,
16+
type SlotsObjectProperty,
1517
type TemplateChildNode,
1618
type TemplateNode,
1719
type TextCallNode,
1820
type VNodeCall,
1921
createArrayExpression,
22+
createObjectProperty,
23+
createSimpleExpression,
2024
getVNodeBlockHelper,
2125
getVNodeHelper,
2226
} from '../ast'
@@ -140,6 +144,7 @@ function walk(
140144
}
141145

142146
let cachedAsArray = false
147+
const cacheKeys = []
143148
if (toCache.length === children.length && node.type === NodeTypes.ELEMENT) {
144149
if (
145150
node.tagType === ElementTypes.ELEMENT &&
@@ -163,6 +168,7 @@ function walk(
163168
// default slot
164169
const slot = getSlotNode(node.codegenNode, 'default')
165170
if (slot) {
171+
cacheKeys.push(context.cached.length)
166172
slot.returns = getCacheExpression(
167173
createArrayExpression(slot.returns as TemplateChildNode[]),
168174
)
@@ -186,6 +192,7 @@ function walk(
186192
slotName.arg &&
187193
getSlotNode(parent.codegenNode, slotName.arg)
188194
if (slot) {
195+
cacheKeys.push(context.cached.length)
189196
slot.returns = getCacheExpression(
190197
createArrayExpression(slot.returns as TemplateChildNode[]),
191198
)
@@ -196,10 +203,28 @@ function walk(
196203

197204
if (!cachedAsArray) {
198205
for (const child of toCache) {
206+
cacheKeys.push(context.cached.length)
199207
child.codegenNode = context.cache(child.codegenNode!)
200208
}
201209
}
202210

211+
if (
212+
cacheKeys.length &&
213+
node.type === NodeTypes.ELEMENT &&
214+
node.codegenNode &&
215+
node.codegenNode.type === NodeTypes.VNODE_CALL &&
216+
node.codegenNode.isComponent &&
217+
node.codegenNode.children &&
218+
(node.codegenNode.children as SlotsObjectExpression).properties
219+
) {
220+
;(node.codegenNode.children as SlotsObjectExpression).properties.push(
221+
createObjectProperty(
222+
`__`,
223+
createSimpleExpression(JSON.stringify(cacheKeys), false),
224+
) as SlotsObjectProperty,
225+
)
226+
}
227+
203228
function getCacheExpression(value: JSChildNode): CacheExpression {
204229
const exp = context.cache(value)
205230
// #6978, #7138, #7114

packages/compiler-core/src/transforms/vSlot.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ export function buildSlots(
342342
: hasForwardedSlots(node.children)
343343
? SlotFlags.FORWARDED
344344
: SlotFlags.STABLE
345-
346345
let slots = createObjectExpression(
347346
slotsProperties.concat(
348347
createObjectProperty(

packages/runtime-core/src/componentSlots.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ export type RawSlots = {
7575
* @internal
7676
*/
7777
_?: SlotFlags
78+
/**
79+
* slot content cache keys
80+
*/
81+
__?: number[]
7882
}
7983

8084
const isInternalKey = (key: string) => key[0] === '_' || key === '$stable'
@@ -170,7 +174,7 @@ const assignSlots = (
170174
// when rendering the optimized slots by manually written render function,
171175
// do not copy the `slots._` compiler flag so that `renderSlot` creates
172176
// slot Fragment with BAIL patchFlag to force full updates
173-
if (optimized || key !== '_') {
177+
if (optimized || !key.startsWith('_')) {
174178
slots[key] = children[key]
175179
}
176180
}

packages/runtime-core/src/renderer.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2262,7 +2262,17 @@ function baseCreateRenderer(
22622262
unregisterHMR(instance)
22632263
}
22642264

2265-
const { bum, scope, job, subTree, um, m, a } = instance
2265+
const {
2266+
bum,
2267+
scope,
2268+
job,
2269+
subTree,
2270+
um,
2271+
m,
2272+
a,
2273+
parent,
2274+
slots: { __: slotCacheKeys },
2275+
} = instance
22662276
invalidateMount(m)
22672277
invalidateMount(a)
22682278

@@ -2271,6 +2281,13 @@ function baseCreateRenderer(
22712281
invokeArrayFns(bum)
22722282
}
22732283

2284+
// remove slots content from parent renderCache
2285+
if (parent && isArray(slotCacheKeys)) {
2286+
slotCacheKeys.forEach(v => {
2287+
parent.renderCache[v] = undefined
2288+
})
2289+
}
2290+
22742291
if (
22752292
__COMPAT__ &&
22762293
isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance)

0 commit comments

Comments
 (0)