Bläddra i källkod

fix(customElement): warn if attr is tagName

daiwei 1 år sedan
förälder
incheckning
b1a12d93c0

+ 18 - 0
packages/runtime-dom/__tests__/customElement.spec.ts

@@ -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()
+  })
 })

+ 10 - 0
packages/runtime-dom/src/apiCustomElement.ts

@@ -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]