vuejs / core

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

Cannot listen for mixed case native event #2460

Open pgbross opened 3 years ago

pgbross commented 3 years ago

Version

3.0.2

Reproduction link

https://codesandbox.io/s/elated-jepsen-822mv?file=/src/main.js

Steps to reproduce

Create a customEvent that dispatches a mixed case native event. Vue component cannot listen for mixed case event.

<div @MDCTab:interacted="onInteracted" @foo="onInteracted"><foo></foo></div>
// foo emits a custom event with mixed case, onInteracted never invoked

What is expected?

The docs say there is no need to use camelCase or PascalCase but need to listen to third party custom event in mixed case.

What is actually happening?

Component's event listener is never called for mixed case native events.

Native event listener, event type is case-sensitive https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

type
A case-sensitive string representing the event type to listen for.

Discovered in the process of updating my vue-material-adapter library to vue-next (it wraps material-components-web which emits mixed case native events)

LinusBorg commented 3 years ago

Hm ... right now we lowercase event names. However we can't easily stop doing that, as for normal events, we have to lowercase at least the first character: 'onClick' -> 'click', so for your event the best we could do easily is 'onMDCTab:interacted' -> mDCTab:interacted, which would also not work.

We would have to find some way (modifier?) to communicate that such an event should not have its case changed at all ....

Relevant code:

https://github.com/vuejs/vue-next/blob/f4621ff5ee4abe924d985177956af3ddc9bb378f/packages/runtime-dom/src/modules/events.ts#L88-L99

flozero commented 2 years ago

I am not able to make simple custom event to work personally... if the prop is an object

eric-hemasystems commented 1 year ago

I hit this also with Rails UJS. It emits events like ajax:beforeSend, ajax:complete, etc. In Vue 2 I had just:

@ajax:beforeSend="beforeRemoteForm"
@ajax:complete="afterRemoteForm"

Now the later one works (since it's all lowercase) but the former does not. I tried things like @ajax.before-send and @ajax.beforesend with no luck. Even v-on="{ beforeSend: beforeRemoteForm }".

I was able to work around it by directly using addEventListener on the element in the mount callback and removeEventListener in the unmount callback.

ssaid-sg commented 1 month ago

Is there any news on this issue?