]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(custom-element): properly resolve props for sync component defs (#12855)
authoredison <daiwei521@126.com>
Thu, 22 May 2025 00:38:27 +0000 (08:38 +0800)
committerGitHub <noreply@github.com>
Thu, 22 May 2025 00:38:27 +0000 (08:38 +0800)
close #12854

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

index cf7b94ed00854e4c61f57e4c382fe47bb4f50123..eee2151716e59d87e052a357f01e3182da9d115c 100644 (file)
@@ -444,6 +444,36 @@ describe('defineCustomElement', () => {
       const e = container.childNodes[0] as VueElement
       expect(e.shadowRoot!.innerHTML).toBe('hello')
     })
+
+    test('prop types validation', async () => {
+      const E = defineCustomElement({
+        props: {
+          num: {
+            type: [Number, String],
+          },
+          bool: {
+            type: Boolean,
+          },
+        },
+        render() {
+          return h('div', [
+            h('span', [`${this.num} is ${typeof this.num}`]),
+            h('span', [`${this.bool} is ${typeof this.bool}`]),
+          ])
+        },
+      })
+
+      customElements.define('my-el-with-type-props', E)
+      render(h('my-el-with-type-props', { num: 1, bool: true }), container)
+      const e = container.childNodes[0] as VueElement
+      // @ts-expect-error
+      expect(e.num).toBe(1)
+      // @ts-expect-error
+      expect(e.bool).toBe(true)
+      expect(e.shadowRoot!.innerHTML).toBe(
+        '<div><span>1 is number</span><span>true is boolean</span></div>',
+      )
+    })
   })
 
   describe('attrs', () => {
index 3a4a34129794c1f05a30ffbfe3449601032d49e7..56b86a5fd9e0cea6803cbbafc8050c06f1c933c9 100644 (file)
@@ -269,11 +269,6 @@ export class VueElement
         this._root = this
       }
     }
-
-    if (!(this._def as ComponentOptions).__asyncLoader) {
-      // for sync component defs we can immediately resolve props
-      this._resolveProps(this._def)
-    }
   }
 
   connectedCallback(): void {
@@ -391,12 +386,7 @@ export class VueElement
         }
       }
       this._numberProps = numberProps
-
-      if (isAsync) {
-        // defining getter/setters on prototype
-        // for sync defs, this already happened in the constructor
-        this._resolveProps(def)
-      }
+      this._resolveProps(def)
 
       // apply CSS
       if (this.shadowRoot) {