fix: fix post watcher fire timing on nested app mounts

close #10005
This commit is contained in:
Evan You 2024-01-08 18:44:28 +08:00
parent d9162dfc2e
commit 3c3561e720
2 changed files with 39 additions and 2 deletions

View File

@ -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.
})

View File

@ -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
}