-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue 3's v-on syntax does not support listening to custom events with capital letters #5401
Comments
<fires-events @Upper=inc1 @lower=inc2> compiles to indistinguishable prop name this is unlikely to change. to work around this limitation, either use a directive or a template ref to add an event listener directly to the dom element. |
@LinusBorg If that's the case then the Vue doesn't get a perfect 100% as mentioned in the docs so the docs need to be updated to reflect that. |
Sure, PRs are welcome. However, consider that we don't prevent you from listening to this event - you can add the event listener with a small custom directive, as mentioned - it's just not supported via |
Sent over a docs PR, but if there's an ergonomic to support arbitrary event names, we could instead update the custom-elements-everywhere test for this feature: https://github.com/webcomponents/custom-elements-everywhere/blob/221ea4744373f34112331949c0d85d4b45e41d69/libraries/vue/src/components.js#L157-L163 |
@rictic thanks! So here's the recommendation: In Vue, one can define custom directives (like that internal ones, i.e. What we would want here is a basic way to add and remove event listeners while preserving the event name casing at all times. This can be achieved with a few lines of code. here's a demo with local registration: SFC Playground Registering this directive globally (in one app's context) would look like this: // v-event:arg"value"
app.directive('event', {
beforeMount(el, { arg, value }) {
el.addEventListener(arg, value)
},
beforeUnmount(el, { arg, value }) {
el.removeEventListener(arg, value)
}
}) Would that be simple enough to be considered as a declarative solution for these tests? |
That works well. Given its small size, what do you think about adding the event directive into Vue by default, just so that it's a pattern that components can rely on existing, and that is more likely to be findable? |
@rictic That's indeed something to consider. However I'm worrried that it's similarity to At the minimum, we should document the limitation and this pattern as a recommended solution in your section about "Vue & Custom Elements" here. |
The Vue docs still say that "Vue scores a perfect 100% in the Custom Elements Everywhere tests" but the tests actually show 91% score: |
@LinusBorg I’ve seen this become a point of friction in migrating from vue2 to vue3 if the app uses a lot of custom elements - you end up with either less idiomatic Vue code throughout by using custom directives for very common event handling, or waiting on publishers of the web components you use to update their library. I find it surprising as a user that you can’t simply consume a web component and listen for the exact event you want - I know this leads to confusion for others, too. The pattern Vue already follows for props with the Happy to open an RFC for this if you think it has any potential - I do think this feels like a gap that Vue itself should handle somehow. |
related RFC discussion |
I believe this was fixed in 3.2.38 via 0739f89. Update: Running the original reproduction against the latest Vue still shows the reported problem. However, I believe that's because You may notice that it works even without the |
Just checked this and yes, the changed mentioned by @Skirtle addresses this issue, though only the related issues in the docs repo were mentjoned in the commit message as this one was already closed at that point. So this issue is now solved. |
As for now, the website https://custom-elements-everywhere.com is still showing Vue as 91% web component compliant. I raise a PR to solve that: webcomponents/custom-elements-everywhere#2074 |
Version
3.2.30
Reproduction link
sfc.vuejs.org/
Steps to reproduce
Notice that the event named 'lower' is being handled by the Vue component, but the event named 'Upper' is not
What is expected?
Event names are an open set, and can include capital letters
What is actually happening?
The event named with a capital letter is not handled
This issue seems to also occur with capital letters in other parts of the event name too
I am a rank Vue novice, and so I may be making a simple error or oversight.
This came up when updating the web site custom-elements-everywhere.com which tracks library and framework support for custom elements. See webcomponents/custom-elements-everywhere#1388
The text was updated successfully, but these errors were encountered: