From 3ecefdf7fcf5522bd546e8fc59d4a7c42c6fd5de Mon Sep 17 00:00:00 2001 From: tycho Date: Tue, 18 Jun 2024 13:06:15 +0800 Subject: [PATCH 1/2] fix(patchProp): prevent setting state as attribute for custom elements --- packages/runtime-dom/src/patchProp.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/src/patchProp.ts b/packages/runtime-dom/src/patchProp.ts index 0da0ff1f272..e7b733c74af 100644 --- a/packages/runtime-dom/src/patchProp.ts +++ b/packages/runtime-dom/src/patchProp.ts @@ -54,7 +54,11 @@ export const patchProp: DOMRendererOptions['patchProp'] = ( ) // #6007 also set form state as attributes so they work with // or libs / extensions that expect attributes - if (key === 'value' || key === 'checked' || key === 'selected') { + // #11163 custom elements may use value as an prop and set it as object + if ( + !el.tagName.includes('-') && + (key === 'value' || key === 'checked' || key === 'selected') + ) { patchAttr(el, key, nextValue, isSVG, parentComponent, key !== 'value') } } else { From cf22a16689ca2be03a50f8c1a56fedea0414dddf Mon Sep 17 00:00:00 2001 From: tycho Date: Tue, 18 Jun 2024 14:12:18 +0800 Subject: [PATCH 2/2] chore: add test --- packages/runtime-dom/__tests__/customElement.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index 276536c2c31..62ba166b030 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -9,6 +9,7 @@ import { inject, nextTick, ref, + render, renderSlot, } from '../src' @@ -137,7 +138,7 @@ describe('defineCustomElement', () => { describe('props', () => { const E = defineCustomElement({ - props: ['foo', 'bar', 'bazQux'], + props: ['foo', 'bar', 'bazQux', 'value'], render() { return [ h('div', null, this.foo), @@ -147,6 +148,12 @@ describe('defineCustomElement', () => { }) customElements.define('my-el-props', E) + test('renders custom element w/ correct object prop value', () => { + render(h('my-el-props', { value: { x: 1 } }), container) + const el = container.children[0] + expect((el as any).value).toEqual({ x: 1 }) + }) + test('props via attribute', async () => { // bazQux should map to `baz-qux` attribute container.innerHTML = ``