core
                                
                                 core copied to clipboard
                                
                                    core copied to clipboard
                            
                            
                            
                        Unexpected behaviour when `a` tag is given a `username` or `password` attribute
Vue version
3.4.21
Link to minimal reproduction
https://play.vuejs.org/#eNp9kctOwzAQRX8leE0T8VhFoRJUXYDEQ8DSEnLTaeLW8Rh73FRU/XfGqVq6QN2N771jnxlvxb1z+TqCKEUVaq8dZQEourG0VbEXuOQDQeeMIuBTllUqaz0s7qRoiVwoi6Lv+7xBbAzkNXZSZDGAt6oDziwQZ8qz5lQIPfo5azP1w0LADkZILfiRIvJ6Fik1fMeNFOOJ0fUqe4aLqlADzgmCuBQUarQL3eTLgJbxtwlMCn7daQP+1ZFGG6Qos8FJnjIG+6dBIx/h8qDXLdSrf/RlYI6SizcPPM4apDh6pHwDtLenHy+w4fpodjiPhtNnzHcIaGJi3Mceop0z9kluoH3sHHrStvkM0w2BDYehEmhK7oa8FPyHkzOj/+He5LdDn7Q73uLXGny6kxfIRn59JXa/+CuwQQ==
Steps to reproduce
- Inspect the atag in the DOM
What is expected?
The username and password attributes fall-through to the underlying a element in the DOM like in vanilla-HTML.
Here's an example fiddle showcasing what I was expected: https://codepen.io/Ross-Alexandra/pen/VwNagGR. If you inspect the a here, you'll see the username, password, and some-other-attribute attributes directly in the DOM.
What is actually happening?
The username & password attributes are being consumed, and prepended to the href as the authentication-part of the URL (ex: <a href="https://foobar:[email protected]"> is being rendered instead of <a href="https://www.google.com" username="foobar" password="baz">).
System Info
No response
Any additional comments?
I ran into this during a migration from Vue 2.7 to Vue 3.1. At some point when our codebase was still on Vue 2.x, we made a refactor which caused one of our components to no longer accept a username prop. This refactor wasn't properly completed however, as some of the references to that component were still passed a username. The root of that component is an a tag, so the username prop being passed to the component fell through to an attribute on the underlying a tag. This bug was then encountered, as that username attribute was prepended onto the href.
If this is working as intended, I was unable to find any documentation pointing this out.
In Vue 3, the default way to add an element property/attribute is through the DOM property - if it exists.
i.e.:
const el = document.createElement('div')
// setting an id happens through the DOM property, because 'id in el' => true
// so Vue does this:
el.id = 'my-id'
// if the property does not exist (and in a few special cases), we set as an attribute instead:
el.setAttribute('custom-attribute', 'my-value')
Now, how does this relate to the reported issue? username and password are actually special DOM properties on anchor elements - and they do exactly what you see here: get/set the username & password from/for the href. But they don't do this if set as attributes - it only works when being set through Javascript as DOM properties.
So in a way, this behavior is unsurprising, assuming one was aware of these special properties (I wasn't as of 5 minutes ago) and Vue's default for setting properties.
It has an easy workaround/fix: force setting these as attributes with .attr:
https://play.vuejs.org/#eNp9kU1vwjAMhv9KlwsXaLWPU9UhbYjDJu1D246RplBMW0jjLHEoGuK/zymCcUDcHD9vosfOVjxYm64DiFwUvnSNpcQDBTuWpsj2DS75QNBarQj4lCSFSmoHi3spaiLr8yzrui6tECsNaYmtFEkePDijWkgVkePkYIE4U24QmVXed+jmRzZTvxF4bGGEVIMbRdLMAgHjn7CRYjzRTblKXuCqyFSvd6IkhoJ8iWbRVOnSo+FxtlFUCraxjQb3ZqlB46XIk55EprTG7rnvkQswPPTLGsrVmf7Ss0fOxbsDnm4NUhwZKVcB7fH08xU2XB9hi/OgOX0BfoBHHaLjPvYYzJy1T3K97VNr0VFjqi8/3RAYfxgqisbkrs9LwX86uTD6v+5tetffk2bHW/xeg4tv8gIZpDfXYvcHoxq1Iw==
Now we just have to discuss if this needs to be handled as another special case in shouldSetAsProp, or if we see this as default behavior in Vue 3:
https://github.com/vuejs/core/blob/3648498ae55e239a54fff710a923531d16bde971/packages/runtime-dom/src/patchProp.ts#L69