]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(custom-element): fix initial attr type casting for programmtically created elements
authorEvan You <yyx990803@gmail.com>
Sat, 9 Oct 2021 22:34:49 +0000 (18:34 -0400)
committerEvan You <yyx990803@gmail.com>
Sat, 9 Oct 2021 22:34:54 +0000 (18:34 -0400)
fix #4772

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

index 7e69ec28ef2a1ce022813dde115b9d1e279f749c..60b51de38937f4a79fc50027c6685eb26aa90404 100644 (file)
@@ -172,6 +172,23 @@ describe('defineCustomElement', () => {
       expect(e.shadowRoot!.innerHTML).toBe(`20 number true boolean 2e1 string`)
     })
 
+    // #4772
+    test('attr casting w/ programmatic creation', () => {
+      const E = defineCustomElement({
+        props: {
+          foo: Number
+        },
+        render() {
+          return `foo type: ${typeof this.foo}`
+        }
+      })
+      customElements.define('my-element-programmatic', E)
+      const el = document.createElement('my-element-programmatic') as any
+      el.setAttribute('foo', '123')
+      container.appendChild(el)
+      expect(el.shadowRoot.innerHTML).toBe(`foo type: number`)
+    })
+
     test('handling properties set before upgrading', () => {
       const E = defineCustomElement({
         props: ['foo'],
index f72b8765f6daf639c912872026956cb263e1ea59..a532da4c6c7f51cd945ee37ff4ab397cf474a70e 100644 (file)
@@ -174,17 +174,6 @@ export class VueElement extends BaseClass {
       }
       this.attachShadow({ mode: 'open' })
     }
-
-    // set initial attrs
-    for (let i = 0; i < this.attributes.length; i++) {
-      this._setAttr(this.attributes[i].name)
-    }
-    // watch future attr changes
-    new MutationObserver(mutations => {
-      for (const m of mutations) {
-        this._setAttr(m.attributeName!)
-      }
-    }).observe(this, { attributes: true })
   }
 
   connectedCallback() {
@@ -212,9 +201,21 @@ export class VueElement extends BaseClass {
     if (this._resolved) {
       return
     }
+    this._resolved = true
+
+    // set initial attrs
+    for (let i = 0; i < this.attributes.length; i++) {
+      this._setAttr(this.attributes[i].name)
+    }
+
+    // watch future attr changes
+    new MutationObserver(mutations => {
+      for (const m of mutations) {
+        this._setAttr(m.attributeName!)
+      }
+    }).observe(this, { attributes: true })
 
     const resolve = (def: InnerComponentDef) => {
-      this._resolved = true
       const { props, styles } = def
       const hasOptions = !isArray(props)
       const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : []