]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix: fix post watcher fire timing on nested app mounts
authorEvan You <yyx990803@gmail.com>
Mon, 8 Jan 2024 10:44:28 +0000 (18:44 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 8 Jan 2024 10:44:28 +0000 (18:44 +0800)
close #10005

packages/runtime-core/__tests__/apiCreateApp.spec.ts
packages/runtime-core/src/renderer.ts

index 300daaaca8be8d0ef8f565b9804d83946db5421b..f8dcd6aee2cecf720f82c568637ef6a97c0eccb4 100644 (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.
 })
index fa1f08c3c9c8a03ee5cbea6ca67e40f92bd1d0a3..cb141d216ffacaefea989a46ca7a572ac6e3d8e4 100644 (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
   }