fix(custom-element): fix custom element props access on initial render
ref: #4792
This commit is contained in:
parent
6916d725a0
commit
4b7f76e36a
@ -191,13 +191,21 @@ describe('defineCustomElement', () => {
|
|||||||
|
|
||||||
test('handling properties set before upgrading', () => {
|
test('handling properties set before upgrading', () => {
|
||||||
const E = defineCustomElement({
|
const E = defineCustomElement({
|
||||||
props: ['foo'],
|
props: {
|
||||||
|
foo: String,
|
||||||
|
dataAge: Number
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
expect(props.foo).toBe('hello')
|
||||||
|
expect(props.dataAge).toBe(5)
|
||||||
|
},
|
||||||
render() {
|
render() {
|
||||||
return `foo: ${this.foo}`
|
return `foo: ${this.foo}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const el = document.createElement('my-el-upgrade') as any
|
const el = document.createElement('my-el-upgrade') as any
|
||||||
el.foo = 'hello'
|
el.foo = 'hello'
|
||||||
|
el.dataset.age = 5
|
||||||
container.appendChild(el)
|
container.appendChild(el)
|
||||||
customElements.define('my-el-upgrade', E)
|
customElements.define('my-el-upgrade', E)
|
||||||
expect(el.shadowRoot.innerHTML).toBe(`foo: hello`)
|
expect(el.shadowRoot.innerHTML).toBe(`foo: hello`)
|
||||||
@ -363,10 +371,10 @@ describe('defineCustomElement', () => {
|
|||||||
|
|
||||||
// should inject styles
|
// should inject styles
|
||||||
expect(e1.shadowRoot!.innerHTML).toBe(
|
expect(e1.shadowRoot!.innerHTML).toBe(
|
||||||
`<div>hello</div><style>div { color: red }</style>`
|
`<style>div { color: red }</style><div>hello</div>`
|
||||||
)
|
)
|
||||||
expect(e2.shadowRoot!.innerHTML).toBe(
|
expect(e2.shadowRoot!.innerHTML).toBe(
|
||||||
`<div>world</div><style>div { color: red }</style>`
|
`<style>div { color: red }</style><div>world</div>`
|
||||||
)
|
)
|
||||||
|
|
||||||
// attr
|
// attr
|
||||||
@ -374,7 +382,7 @@ describe('defineCustomElement', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect((e1 as any).msg).toBe('attr')
|
expect((e1 as any).msg).toBe('attr')
|
||||||
expect(e1.shadowRoot!.innerHTML).toBe(
|
expect(e1.shadowRoot!.innerHTML).toBe(
|
||||||
`<div>attr</div><style>div { color: red }</style>`
|
`<style>div { color: red }</style><div>attr</div>`
|
||||||
)
|
)
|
||||||
|
|
||||||
// props
|
// props
|
||||||
@ -382,7 +390,7 @@ describe('defineCustomElement', () => {
|
|||||||
;(e1 as any).msg = 'prop'
|
;(e1 as any).msg = 'prop'
|
||||||
expect(e1.getAttribute('msg')).toBe('prop')
|
expect(e1.getAttribute('msg')).toBe('prop')
|
||||||
expect(e1.shadowRoot!.innerHTML).toBe(
|
expect(e1.shadowRoot!.innerHTML).toBe(
|
||||||
`<div>prop</div><style>div { color: red }</style>`
|
`<style>div { color: red }</style><div>prop</div>`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -391,6 +399,9 @@ describe('defineCustomElement', () => {
|
|||||||
defineAsyncComponent(() => {
|
defineAsyncComponent(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
props: ['msg'],
|
props: ['msg'],
|
||||||
|
setup(props) {
|
||||||
|
expect(typeof props.msg).toBe('string')
|
||||||
|
},
|
||||||
render(this: any) {
|
render(this: any) {
|
||||||
return h('div', this.msg)
|
return h('div', this.msg)
|
||||||
}
|
}
|
||||||
@ -429,6 +440,9 @@ describe('defineCustomElement', () => {
|
|||||||
defineAsyncComponent(() => {
|
defineAsyncComponent(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
props: { n: Number },
|
props: { n: Number },
|
||||||
|
setup(props) {
|
||||||
|
expect(props.n).toBe(20)
|
||||||
|
},
|
||||||
render(this: any) {
|
render(this: any) {
|
||||||
return h('div', this.n + ',' + typeof this.n)
|
return h('div', this.n + ',' + typeof this.n)
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,6 @@ export class VueElement extends BaseClass {
|
|||||||
this._connected = true
|
this._connected = true
|
||||||
if (!this._instance) {
|
if (!this._instance) {
|
||||||
this._resolveDef()
|
this._resolveDef()
|
||||||
this._update()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,17 +230,15 @@ export class VueElement extends BaseClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (numberProps) {
|
|
||||||
this._numberProps = numberProps
|
this._numberProps = numberProps
|
||||||
this._update()
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if there are props set pre-upgrade or connect
|
// check if there are props set pre-upgrade or connect
|
||||||
for (const key of Object.keys(this)) {
|
for (const key of Object.keys(this)) {
|
||||||
if (key[0] !== '_') {
|
if (key[0] !== '_') {
|
||||||
this._setProp(key, this[key as keyof this])
|
this._setProp(key, this[key as keyof this], true, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// defining getter/setters on prototype
|
// defining getter/setters on prototype
|
||||||
for (const key of rawKeys.map(camelize)) {
|
for (const key of rawKeys.map(camelize)) {
|
||||||
Object.defineProperty(this, key, {
|
Object.defineProperty(this, key, {
|
||||||
@ -253,7 +250,12 @@ export class VueElement extends BaseClass {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply CSS
|
||||||
this._applyStyles(styles)
|
this._applyStyles(styles)
|
||||||
|
|
||||||
|
// initial render
|
||||||
|
this._update()
|
||||||
}
|
}
|
||||||
|
|
||||||
const asyncDef = (this._def as ComponentOptions).__asyncLoader
|
const asyncDef = (this._def as ComponentOptions).__asyncLoader
|
||||||
@ -282,10 +284,15 @@ export class VueElement extends BaseClass {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected _setProp(key: string, val: any, shouldReflect = true) {
|
protected _setProp(
|
||||||
|
key: string,
|
||||||
|
val: any,
|
||||||
|
shouldReflect = true,
|
||||||
|
shouldUpdate = true
|
||||||
|
) {
|
||||||
if (val !== this._props[key]) {
|
if (val !== this._props[key]) {
|
||||||
this._props[key] = val
|
this._props[key] = val
|
||||||
if (this._instance) {
|
if (shouldUpdate && this._instance) {
|
||||||
this._update()
|
this._update()
|
||||||
}
|
}
|
||||||
// reflect
|
// reflect
|
||||||
|
Loading…
x
Reference in New Issue
Block a user