Skip to content

Commit

Permalink
fix(custom-element): delete prop on attribute removal
Browse files Browse the repository at this point in the history
close #11276
  • Loading branch information
yyx990803 committed Aug 8, 2024
1 parent be84f33 commit 506c4c5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
21 changes: 21 additions & 0 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1241,4 +1241,25 @@ describe('defineCustomElement', () => {
expect(e.shadowRoot!.innerHTML).toBe(`<div>fooValue</div>`)
app.unmount()
})

// #11276
test('delete prop on attr removal', async () => {
const E = defineCustomElement({
props: {
boo: {
type: Boolean,
},
},
render() {
return this.boo + ',' + typeof this.boo
},
})
customElements.define('el-attr-removal', E)
container.innerHTML = '<el-attr-removal boo>'
const e = container.childNodes[0] as VueElement
expect(e.shadowRoot!.innerHTML).toBe(`true,boolean`)
e.removeAttribute('boo')
await nextTick()
expect(e.shadowRoot!.innerHTML).toBe(`false,boolean`)
})
})
14 changes: 11 additions & 3 deletions packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ import {
} from '@vue/shared'
import { createApp, createSSRApp, render } from '.'

// marker for attr removal
const REMOVAL = {}

export type VueElementConstructor<P = {}> = {
new (initialProps?: Record<string, any>): VueElement & P
}
Expand Down Expand Up @@ -455,9 +458,10 @@ export class VueElement

protected _setAttr(key: string) {
if (key.startsWith('data-v-')) return
let value = this.hasAttribute(key) ? this.getAttribute(key) : undefined
const has = this.hasAttribute(key)
let value = has ? this.getAttribute(key) : REMOVAL
const camelKey = camelize(key)
if (this._numberProps && this._numberProps[camelKey]) {
if (has && this._numberProps && this._numberProps[camelKey]) {
value = toNumber(value)
}
this._setProp(camelKey, value, false, true)
Expand All @@ -475,7 +479,11 @@ export class VueElement
*/
_setProp(key: string, val: any, shouldReflect = true, shouldUpdate = false) {
if (val !== this._props[key]) {
this._props[key] = val
if (val === REMOVAL) {
delete this._props[key]
} else {
this._props[key] = val
}
if (shouldUpdate && this._instance) {
this._update()
}
Expand Down

0 comments on commit 506c4c5

Please sign in to comment.