]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(customElement): warn if attr is tagName
authordaiwei <daiwei521@126.com>
Tue, 8 Oct 2024 02:16:38 +0000 (10:16 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 8 Oct 2024 02:16:38 +0000 (10:16 +0800)
packages/runtime-dom/__tests__/customElement.spec.ts
packages/runtime-dom/src/apiCustomElement.ts

index ef5051f42f7567fe63973c13b62fbf0eeb132b3b..68e0f55a06eff5209b1c79aaf0155f3d84e17b23 100644 (file)
@@ -1386,4 +1386,22 @@ describe('defineCustomElement', () => {
     await nextTick()
     expect(e.shadowRoot!.innerHTML).toBe(`false,boolean`)
   })
+
+  test('avoid overriding tagName', async () => {
+    const E = defineCustomElement({
+      props: {
+        tagName: {
+          type: String,
+        },
+      },
+      render() {
+        return this.tagName
+      },
+    })
+    customElements.define('el-attr-tag-name', E)
+    container.innerHTML = '<el-attr-tag-name tag-name="foo">'
+    const e = container.childNodes[0] as VueElement
+    expect(e.tagName).toBe(`EL-ATTR-TAG-NAME`)
+    expect(`[Vue warn]: Failed setting prop "tagName" `).toHaveBeenWarned()
+  })
 })
index 6ddaf89713016db4582689ec2c2dec0cd349b21e..a0a8a3a7c32b7798588bbd864e71078fc55de449 100644 (file)
@@ -452,6 +452,7 @@ export class VueElement
 
     // defining getter/setters on prototype
     for (const key of declaredPropKeys.map(camelize)) {
+      if (key === 'tagName') continue
       Object.defineProperty(this, key, {
         get() {
           return this._getProp(key)
@@ -490,6 +491,15 @@ export class VueElement
     shouldReflect = true,
     shouldUpdate = false,
   ): void {
+    if (key === 'tagName') {
+      if (__DEV__) {
+        warn(
+          `Failed setting prop "${key}" on <${this.tagName.toLowerCase()}>: ` +
+            `TypeError: Cannot set property tagName of #<Element> which has only a getter`,
+        )
+      }
+      return
+    }
     if (val !== this._props[key]) {
       if (val === REMOVAL) {
         delete this._props[key]