Browse Source

fix(runtime-core): properly update async component nested in KeepAlive (#11917)

close #11916
edison 1 year ago
parent
commit
7fe6c795a1

+ 33 - 0
packages/runtime-core/__tests__/apiAsyncComponent.spec.ts

@@ -843,4 +843,37 @@ describe('api: defineAsyncComponent', () => {
     await timeout()
     expect(serializeInner(root)).toBe('Bar')
   })
+
+  // 11916
+  test('with KeepAlive + include', async () => {
+    const spy = vi.fn()
+    let resolve: (comp: Component) => void
+
+    const Foo = defineAsyncComponent(
+      () =>
+        new Promise(r => {
+          resolve = r as any
+        }),
+    )
+
+    const root = nodeOps.createElement('div')
+    const app = createApp({
+      render: () => h(KeepAlive, { include: 'Foo' }, [h(Foo)]),
+    })
+
+    app.mount(root)
+    await nextTick()
+
+    resolve!({
+      name: 'Foo',
+      setup() {
+        onActivated(spy)
+        return () => 'Foo'
+      },
+    })
+
+    await timeout()
+    expect(serializeInner(root)).toBe('Foo')
+    expect(spy).toBeCalledTimes(1)
+  })
 })

+ 1 - 2
packages/runtime-core/src/apiAsyncComponent.ts

@@ -14,7 +14,6 @@ import { warn } from './warning'
 import { ref } from '@vue/reactivity'
 import { ErrorCodes, handleError } from './errorHandling'
 import { isKeepAlive } from './components/KeepAlive'
-import { queueJob } from './scheduler'
 import { markAsyncBoundary } from './helpers/useId'
 import { type HydrationStrategy, forEachElement } from './hydrationStrategies'
 
@@ -210,7 +209,7 @@ export function defineAsyncComponent<
           if (instance.parent && isKeepAlive(instance.parent.vnode)) {
             // parent is keep-alive, force update so the loaded component's
             // name is taken into account
-            queueJob(instance.parent.update)
+            instance.parent.update()
           }
         })
         .catch(err => {