vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.89k stars 8.36k forks source link

defineCustomElement can accidentally override members of the Element prototype #12124

Open lennartbuit opened 1 month ago

lennartbuit commented 1 month ago

Vue version

3.4.5

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-aob5zf?file=index.html

Steps to reproduce

I defined a Vue component with tagName as a property, and used that, together with defineCustomElement to define the hello-world webcomponent.

tagName is obviously already defined in the Element prototype.

What is expected?

I expected to maybe be able to create only the tag-name attribute (and no matching tagName property), or a warning that I'm accidentally overwriting important Element properties. Or a way to remap the tag-name attribute to a different property.

What is actually happening?

Vue's defineCustomElement happily overwrites the tagName property of the Element prototype without warning.

I know this is user error, but I was surprised that Vue let me.

System Info

No response

Any additional comments?

In Lit, you can be explicit about what property/attribute something maps to, that would be super cool here too:

@property({ attribute: 'tag-name' }) nonConfictingPropertyName;

We managed to put us in a situation where the attribute (which is not problematic) is causing issues because Vue generated an override for the tagName property (which is problematic), while we don't use that often.

edison1105 commented 1 month ago

If your code relies on tagName, maybe you can use nodeName instead

document.querySelector("hello-world").nodeName // 'HELLO-WORLD'