Skip to content

Commit

Permalink
fix(custom-elements): properties set pre-upgrade should not show up i…
Browse files Browse the repository at this point in the history
…n $attrs
  • Loading branch information
yyx990803 committed Nov 11, 2022
1 parent 5e50909 commit afe8899
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
27 changes: 27 additions & 0 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,33 @@ describe('defineCustomElement', () => {
})
})

describe('attrs', () => {
const E = defineCustomElement({
render() {
return [h('div', null, this.$attrs.foo as string)]
}
})
customElements.define('my-el-attrs', E)

test('attrs via attribute', async () => {
container.innerHTML = `<my-el-attrs foo="hello"></my-el-attrs>`
const e = container.childNodes[0] as VueElement
expect(e.shadowRoot!.innerHTML).toBe('<div>hello</div>')

e.setAttribute('foo', 'changed')
await nextTick()
expect(e.shadowRoot!.innerHTML).toBe('<div>changed</div>')
})

test('non-declared properties should not show up in $attrs', () => {
const e = new E()
// @ts-ignore
e.foo = '123'
container.appendChild(e)
expect(e.shadowRoot!.innerHTML).toBe('<div></div>')
})
})

describe('emits', () => {
const CompDef = defineComponent({
setup(_, { emit }) {
Expand Down
18 changes: 6 additions & 12 deletions packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,12 @@ export class VueElement extends BaseClass {
}).observe(this, { attributes: true })

const resolve = (def: InnerComponentDef) => {
const { props = {}, styles } = def
const hasOptions = !isArray(props)
const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : []
const { props, styles } = def
const declaredPropKeys = isArray(props) ? props : Object.keys(props || {})

// cast Number-type props set before resolve
let numberProps
if (hasOptions) {
if (props && !isArray(props)) {
for (const key in this._props) {
const opt = props[key]
if (opt === Number || (opt && opt.type === Number)) {
Expand All @@ -247,18 +246,13 @@ export class VueElement extends BaseClass {

// check if there are props set pre-upgrade or connect
for (const key of Object.keys(this)) {
if (key[0] !== '_') {
this._setProp(
key,
this[key as keyof this],
rawKeys.includes(key),
false
)
if (key[0] !== '_' && declaredPropKeys.includes(key)) {
this._setProp(key, this[key as keyof this], true, false)
}
}

// defining getter/setters on prototype
for (const key of rawKeys.map(camelize)) {
for (const key of declaredPropKeys.map(camelize)) {
Object.defineProperty(this, key, {
get() {
return this._getProp(key)
Expand Down

0 comments on commit afe8899

Please sign in to comment.