Skip to content

Commit afe8899

Browse files
committed
fix(custom-elements): properties set pre-upgrade should not show up in $attrs
1 parent 5e50909 commit afe8899

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

+27
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,33 @@ describe('defineCustomElement', () => {
230230
})
231231
})
232232

233+
describe('attrs', () => {
234+
const E = defineCustomElement({
235+
render() {
236+
return [h('div', null, this.$attrs.foo as string)]
237+
}
238+
})
239+
customElements.define('my-el-attrs', E)
240+
241+
test('attrs via attribute', async () => {
242+
container.innerHTML = `<my-el-attrs foo="hello"></my-el-attrs>`
243+
const e = container.childNodes[0] as VueElement
244+
expect(e.shadowRoot!.innerHTML).toBe('<div>hello</div>')
245+
246+
e.setAttribute('foo', 'changed')
247+
await nextTick()
248+
expect(e.shadowRoot!.innerHTML).toBe('<div>changed</div>')
249+
})
250+
251+
test('non-declared properties should not show up in $attrs', () => {
252+
const e = new E()
253+
// @ts-ignore
254+
e.foo = '123'
255+
container.appendChild(e)
256+
expect(e.shadowRoot!.innerHTML).toBe('<div></div>')
257+
})
258+
})
259+
233260
describe('emits', () => {
234261
const CompDef = defineComponent({
235262
setup(_, { emit }) {

packages/runtime-dom/src/apiCustomElement.ts

+6-12
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,12 @@ export class VueElement extends BaseClass {
228228
}).observe(this, { attributes: true })
229229

230230
const resolve = (def: InnerComponentDef) => {
231-
const { props = {}, styles } = def
232-
const hasOptions = !isArray(props)
233-
const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : []
231+
const { props, styles } = def
232+
const declaredPropKeys = isArray(props) ? props : Object.keys(props || {})
234233

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

248247
// check if there are props set pre-upgrade or connect
249248
for (const key of Object.keys(this)) {
250-
if (key[0] !== '_') {
251-
this._setProp(
252-
key,
253-
this[key as keyof this],
254-
rawKeys.includes(key),
255-
false
256-
)
249+
if (key[0] !== '_' && declaredPropKeys.includes(key)) {
250+
this._setProp(key, this[key as keyof this], true, false)
257251
}
258252
}
259253

260254
// defining getter/setters on prototype
261-
for (const key of rawKeys.map(camelize)) {
255+
for (const key of declaredPropKeys.map(camelize)) {
262256
Object.defineProperty(this, key, {
263257
get() {
264258
return this._getProp(key)

0 commit comments

Comments
 (0)