Skip to content

Commit dfe667c

Browse files
authored
fix(KeepAlive): use resolved component name for async components in cache pruning (#14212)
close #14210
1 parent d8a2de4 commit dfe667c

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

packages/runtime-core/__tests__/components/KeepAlive.spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,4 +1173,53 @@ describe('KeepAlive', () => {
11731173
expect(deactivatedHome).toHaveBeenCalledTimes(0)
11741174
expect(unmountedHome).toHaveBeenCalledTimes(1)
11751175
})
1176+
1177+
test('should work with async component when update `include` props', async () => {
1178+
let resolve: (comp: Component) => void
1179+
const AsyncComp = defineAsyncComponent(
1180+
() =>
1181+
new Promise(r => {
1182+
resolve = r as any
1183+
}),
1184+
)
1185+
1186+
const toggle = ref(true)
1187+
const instanceRef = ref<any>(null)
1188+
const keepaliveInclude = ref(['Foo'])
1189+
const App = {
1190+
render: () => {
1191+
return h(KeepAlive, { include: keepaliveInclude.value }, () =>
1192+
toggle.value ? h(AsyncComp, { ref: instanceRef }) : null,
1193+
)
1194+
},
1195+
}
1196+
1197+
render(h(App), root)
1198+
// async component has not been resolved
1199+
expect(serializeInner(root)).toBe('<!---->')
1200+
1201+
resolve!({
1202+
name: 'Foo',
1203+
data: () => ({ count: 0 }),
1204+
render() {
1205+
return h('p', this.count)
1206+
},
1207+
})
1208+
1209+
await timeout()
1210+
// resolved
1211+
expect(serializeInner(root)).toBe('<p>0</p>')
1212+
1213+
// change state + toggle out + update `include` props
1214+
instanceRef.value.count++
1215+
toggle.value = false
1216+
keepaliveInclude.value = ['Foo']
1217+
await nextTick()
1218+
expect(serializeInner(root)).toBe('<!---->')
1219+
1220+
// toggle in, state should be maintained
1221+
toggle.value = true
1222+
await nextTick()
1223+
expect(serializeInner(root)).toBe('<p>1</p>')
1224+
})
11761225
})

packages/runtime-core/src/components/KeepAlive.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,13 @@ const KeepAliveImpl: ComponentOptions = {
202202

203203
function pruneCache(filter: (name: string) => boolean) {
204204
cache.forEach((vnode, key) => {
205-
const name = getComponentName(vnode.type as ConcreteComponent)
205+
// for async components, name check should be based in its loaded
206+
// inner component if available
207+
const name = getComponentName(
208+
isAsyncWrapper(vnode)
209+
? (vnode.type as ComponentOptions).__asyncResolved || {}
210+
: (vnode.type as ConcreteComponent),
211+
)
206212
if (name && !filter(name)) {
207213
pruneCacheEntry(key)
208214
}

0 commit comments

Comments
 (0)