From: Evan You Date: Wed, 7 Aug 2024 09:43:29 +0000 (+0800) Subject: fix(custom-element): fix custom-element double render on immediate prop change X-Git-Tag: v3.4.37~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=978ff3c1dbff9c93ec284c1804d3c77331ea33f8;p=thirdparty%2Fvuejs%2Fcore.git fix(custom-element): fix custom-element double render on immediate prop change fix #9885 close #11335 --- diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index db674f987d..49ef212039 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -2352,13 +2352,13 @@ function baseCreateRenderer( namespace, ) } + container._vnode = vnode if (!isFlushing) { isFlushing = true flushPreFlushCbs() flushPostFlushCbs() isFlushing = false } - container._vnode = vnode } const internals: RendererInternals = { diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index 62ba166b03..449a85480c 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -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', + ) + }) })