diff --git a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts index 799108dca8a..62aebd1a995 100644 --- a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts @@ -1,4 +1,5 @@ import { + Suspense, defineComponent, h, nextTick, @@ -537,4 +538,39 @@ describe('api: template refs', () => { '
[object Object],[object Object]
', ) }) + + it('with async component', async () => { + const deps: Promise[] = [] + const spy = vi.fn() + + const AsyncChild = defineComponent({ + async setup(_, { expose }) { + const p = new Promise(r => setTimeout(r, 1)) + deps.push(p.then(() => Promise.resolve())) + await p + expose({ foo: spy }) + return () => h('div', 'child') + }, + }) + + const childRef = ref(null) + const App = { + setup() { + return { refKey: childRef } + }, + render() { + return h(Suspense, null, { default: h(AsyncChild, { ref: 'refKey' }) }) + }, + } + + const root = nodeOps.createElement('div') + render(h(App), root) + + await Promise.all(deps) + await nextTick() + + expect((childRef.value as any).foo).toBe(spy) + ;(childRef.value as any).foo() + expect(spy).toBeCalledTimes(1) + }) }) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index 1ffe3035794..c6da0b14a60 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -28,6 +28,13 @@ export function setRef( vnode: VNode, isUnmount = false, ): void { + if (parentSuspense) { + queuePostRenderEffect(() => { + setRef(rawRef, oldRawRef, null, vnode, isUnmount) + }, parentSuspense) + return + } + if (isArray(rawRef)) { rawRef.forEach((r, i) => setRef(