diff --git a/packages/runtime-core/__tests__/apiCreateApp.spec.ts b/packages/runtime-core/__tests__/apiCreateApp.spec.ts index 300daaaca8b..f8dcd6aee2c 100644 --- a/packages/runtime-core/__tests__/apiCreateApp.spec.ts +++ b/packages/runtime-core/__tests__/apiCreateApp.spec.ts @@ -5,12 +5,15 @@ import { getCurrentInstance, h, inject, + nextTick, nodeOps, + onMounted, provide, ref, resolveComponent, resolveDirective, serializeInner, + watch, withDirectives, } from '@vue/runtime-test' @@ -551,6 +554,35 @@ describe('api: createApp', () => { ).not.toHaveBeenWarned() }) + // #10005 + test('flush order edge case on nested createApp', async () => { + const order: string[] = [] + const App = defineComponent({ + setup(props) { + const message = ref('m1') + watch( + message, + () => { + order.push('post watcher') + }, + { flush: 'post' }, + ) + onMounted(() => { + message.value = 'm2' + createApp(() => '').mount(nodeOps.createElement('div')) + }) + return () => { + order.push('render') + return h('div', [message.value]) + } + }, + }) + + createApp(App).mount(nodeOps.createElement('div')) + await nextTick() + expect(order).toMatchObject(['render', 'render', 'post watcher']) + }) + // config.compilerOptions is tested in packages/vue since it is only // supported in the full build. }) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index fa1f08c3c9c..cb141d216ff 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -2348,6 +2348,7 @@ function baseCreateRenderer( return hostNextSibling((vnode.anchor || vnode.el)!) } + let isFlushing = false const render: RootRenderFunction = (vnode, container, namespace) => { if (vnode == null) { if (container._vnode) { @@ -2364,8 +2365,12 @@ function baseCreateRenderer( namespace, ) } - flushPreFlushCbs() - flushPostFlushCbs() + if (!isFlushing) { + isFlushing = true + flushPreFlushCbs() + flushPostFlushCbs() + isFlushing = false + } container._vnode = vnode }