]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(custom-element): fix custom-element double render on immediate prop change
authorEvan You <evan@vuejs.org>
Wed, 7 Aug 2024 09:43:29 +0000 (17:43 +0800)
committerEvan You <evan@vuejs.org>
Wed, 7 Aug 2024 09:44:11 +0000 (17:44 +0800)
fix #9885
close #11335

packages/runtime-core/src/renderer.ts
packages/runtime-dom/__tests__/customElement.spec.ts

index db674f987d81eefaaecf4f191991c91c3ddb3f4a..49ef212039b8039852a0f5256e2b6dafa38e0dbf 100644 (file)
@@ -2352,13 +2352,13 @@ function baseCreateRenderer(
         namespace,
       )
     }
+    container._vnode = vnode
     if (!isFlushing) {
       isFlushing = true
       flushPreFlushCbs()
       flushPostFlushCbs()
       isFlushing = false
     }
-    container._vnode = vnode
   }
 
   const internals: RendererInternals = {
index 62ba166b030fd64172c4434b987504c9084b3eb4..449a85480c5ed80b3d9f078637e92d7dbb0203d2 100644 (file)
@@ -108,6 +108,7 @@ describe('defineCustomElement', () => {
       myInputEl.removeAttribute('value')
       await nextTick()
       expect(inputEl.value).toBe('')
+      app.unmount()
     })
 
     test('should not unmount on move', async () => {
@@ -772,4 +773,33 @@ describe('defineCustomElement', () => {
       )
     })
   })
+
+  // #9885
+  test('avoid double mount when prop is set immediately after mount', () => {
+    customElements.define(
+      'my-input-dupe',
+      defineCustomElement({
+        props: {
+          value: String,
+        },
+        render() {
+          return 'hello'
+        },
+      }),
+    )
+    createApp({
+      render() {
+        return h('div', [
+          h('my-input-dupe', {
+            onVnodeMounted(vnode) {
+              vnode.el!.value = 'fesfes'
+            },
+          }),
+        ])
+      },
+    }).mount(container)
+    expect(container.children[0].children[0].shadowRoot?.innerHTML).toBe(
+      'hello',
+    )
+  })
 })