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 = ``
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 {