mirror of https://github.com/vuejs/core.git
parent
be84f33ab0
commit
506c4c53fd
|
@ -1241,4 +1241,25 @@ describe('defineCustomElement', () => {
|
||||||
expect(e.shadowRoot!.innerHTML).toBe(`<div>fooValue</div>`)
|
expect(e.shadowRoot!.innerHTML).toBe(`<div>fooValue</div>`)
|
||||||
app.unmount()
|
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`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,6 +42,9 @@ import {
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { createApp, createSSRApp, render } from '.'
|
import { createApp, createSSRApp, render } from '.'
|
||||||
|
|
||||||
|
// marker for attr removal
|
||||||
|
const REMOVAL = {}
|
||||||
|
|
||||||
export type VueElementConstructor<P = {}> = {
|
export type VueElementConstructor<P = {}> = {
|
||||||
new (initialProps?: Record<string, any>): VueElement & P
|
new (initialProps?: Record<string, any>): VueElement & P
|
||||||
}
|
}
|
||||||
|
@ -455,9 +458,10 @@ export class VueElement
|
||||||
|
|
||||||
protected _setAttr(key: string) {
|
protected _setAttr(key: string) {
|
||||||
if (key.startsWith('data-v-')) return
|
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)
|
const camelKey = camelize(key)
|
||||||
if (this._numberProps && this._numberProps[camelKey]) {
|
if (has && this._numberProps && this._numberProps[camelKey]) {
|
||||||
value = toNumber(value)
|
value = toNumber(value)
|
||||||
}
|
}
|
||||||
this._setProp(camelKey, value, false, true)
|
this._setProp(camelKey, value, false, true)
|
||||||
|
@ -475,7 +479,11 @@ export class VueElement
|
||||||
*/
|
*/
|
||||||
_setProp(key: string, val: any, shouldReflect = true, shouldUpdate = false) {
|
_setProp(key: string, val: any, shouldReflect = true, shouldUpdate = false) {
|
||||||
if (val !== this._props[key]) {
|
if (val !== this._props[key]) {
|
||||||
|
if (val === REMOVAL) {
|
||||||
|
delete this._props[key]
|
||||||
|
} else {
|
||||||
this._props[key] = val
|
this._props[key] = val
|
||||||
|
}
|
||||||
if (shouldUpdate && this._instance) {
|
if (shouldUpdate && this._instance) {
|
||||||
this._update()
|
this._update()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue