Subscribe on changes!

Cannot listen for mixed case native event

avatar
Oct 22nd 2020

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)

avatar
Oct 22nd 2020

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

avatar
Jan 24th 2022

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

avatar
Feb 7th 2023

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.