Skip to content

Commit e16e9a7

Browse files
authored
fix(custom-element): properly remove hyphenated attribute (#12143)
close #12139
1 parent 35785f3 commit e16e9a7

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

+35
Original file line numberDiff line numberDiff line change
@@ -1386,4 +1386,39 @@ describe('defineCustomElement', () => {
13861386
await nextTick()
13871387
expect(e.shadowRoot!.innerHTML).toBe(`false,boolean`)
13881388
})
1389+
1390+
test('hyphenated attr removal', async () => {
1391+
const E = defineCustomElement({
1392+
props: {
1393+
fooBar: {
1394+
type: Boolean,
1395+
},
1396+
},
1397+
render() {
1398+
return this.fooBar
1399+
},
1400+
})
1401+
customElements.define('el-hyphenated-attr-removal', E)
1402+
const toggle = ref(true)
1403+
const Comp = {
1404+
render() {
1405+
return h('el-hyphenated-attr-removal', {
1406+
'foo-bar': toggle.value ? '' : null,
1407+
})
1408+
},
1409+
}
1410+
render(h(Comp), container)
1411+
const el = container.children[0]
1412+
expect(el.hasAttribute('foo-bar')).toBe(true)
1413+
expect((el as any).outerHTML).toBe(
1414+
`<el-hyphenated-attr-removal foo-bar=""></el-hyphenated-attr-removal>`,
1415+
)
1416+
1417+
toggle.value = false
1418+
await nextTick()
1419+
expect(el.hasAttribute('foo-bar')).toBe(false)
1420+
expect((el as any).outerHTML).toBe(
1421+
`<el-hyphenated-attr-removal></el-hyphenated-attr-removal>`,
1422+
)
1423+
})
13891424
})

packages/runtime-dom/src/modules/props.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export function patchDOMProp(
88
key: string,
99
value: any,
1010
parentComponent: any,
11+
attrName?: string,
1112
): void {
1213
// __UNSAFE__
1314
// Reason: potentially setting innerHTML.
@@ -106,5 +107,5 @@ export function patchDOMProp(
106107
)
107108
}
108109
}
109-
needRemove && el.removeAttribute(key)
110+
needRemove && el.removeAttribute(attrName || key)
110111
}

packages/runtime-dom/src/patchProp.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const patchProp: DOMRendererOptions['patchProp'] = (
6262
(el as VueElement)._isVueCE &&
6363
(/[A-Z]/.test(key) || !isString(nextValue))
6464
) {
65-
patchDOMProp(el, camelize(key), nextValue, parentComponent)
65+
patchDOMProp(el, camelize(key), nextValue, parentComponent, key)
6666
} else {
6767
// special case for <input v-model type="checkbox"> with
6868
// :true-value & :false-value

0 commit comments

Comments
 (0)