fix(runtime-dom): prevent setting state as attribute for custom elements (#11165)

close #11163
This commit is contained in:
Tycho 2024-06-22 16:42:12 +08:00 committed by GitHub
parent 3bd79e3e5e
commit 8ae4c293ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 2 deletions

View File

@ -9,6 +9,7 @@ import {
inject, inject,
nextTick, nextTick,
ref, ref,
render,
renderSlot, renderSlot,
} from '../src' } from '../src'
@ -137,7 +138,7 @@ describe('defineCustomElement', () => {
describe('props', () => { describe('props', () => {
const E = defineCustomElement({ const E = defineCustomElement({
props: ['foo', 'bar', 'bazQux'], props: ['foo', 'bar', 'bazQux', 'value'],
render() { render() {
return [ return [
h('div', null, this.foo), h('div', null, this.foo),
@ -147,6 +148,12 @@ describe('defineCustomElement', () => {
}) })
customElements.define('my-el-props', E) 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 () => { test('props via attribute', async () => {
// bazQux should map to `baz-qux` attribute // bazQux should map to `baz-qux` attribute
container.innerHTML = `<my-el-props foo="hello" baz-qux="bye"></my-el-props>` container.innerHTML = `<my-el-props foo="hello" baz-qux="bye"></my-el-props>`

View File

@ -54,7 +54,11 @@ export const patchProp: DOMRendererOptions['patchProp'] = (
) )
// #6007 also set form state as attributes so they work with // #6007 also set form state as attributes so they work with
// <input type="reset"> or libs / extensions that expect attributes // <input type="reset"> 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') patchAttr(el, key, nextValue, isSVG, parentComponent, key !== 'value')
} }
} else { } else {