Skip to content

Commit

Permalink
feat(runtime-dom): Support attrs in custom-elements.
Browse files Browse the repository at this point in the history
  • Loading branch information
ygj6 committed Jan 17, 2022
1 parent 3adfc0f commit a1cc63f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
32 changes: 32 additions & 0 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,38 @@ 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('attrs via properties', async () => {
const e = new E() as any
e.foo = 'one'
container.appendChild(e)
expect(e.shadowRoot!.innerHTML).toBe('<div>one</div>')

e.foo = 'two'
await nextTick()
expect(e.shadowRoot!.innerHTML).toBe('<div>two</div>')
})
})

describe('emits', () => {
const E = defineCustomElement({
setup(_, { emit }) {
Expand Down
11 changes: 9 additions & 2 deletions packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,19 @@ export class VueElement extends BaseClass {
const resolve = (def: InnerComponentDef) => {
const { props, styles } = def
const hasOptions = !isArray(props)
const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : []
const rawKeys = [
...new Set(
Object.keys(this._props).concat(
props ? (hasOptions ? Object.keys(props) : props) : []
)
)
]

// cast Number-type props set before resolve
let numberProps
if (hasOptions) {
for (const key in this._props) {
const opt = props[key]
const opt = props && props[key]
if (opt === Number || (opt && opt.type === Number)) {
this._props[key] = toNumber(this._props[key])
;(numberProps || (numberProps = Object.create(null)))[key] = true
Expand All @@ -235,6 +241,7 @@ 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] !== '_') {
rawKeys.includes(key) || rawKeys.push(key)
this._setProp(key, this[key as keyof this], true, false)
}
}
Expand Down

0 comments on commit a1cc63f

Please sign in to comment.