Skip to content
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

Custom Events with uppercase characters no longer work in Vue #2804

Closed
alexanderbenavides opened this issue Jan 19, 2021 · 8 comments
Closed
Labels
ionitron: support This is a support question

Comments

@alexanderbenavides
Copy link

I created an input in stenciljs and I have register a valueChanged event in there. Then I want to use the input in vue with the v-model directive. But the the event @valueChanged does not work in vue 3, but it does in vue 2.

Vue 3:

image

vue 2:
image

My code in vue2 and vue3 are the same:

<template>
    <cb-input label="Name: " @valueChanged="onValueChanged"></cb-input>
</template>

<script>

export default {
  name: 'App',
  components: {},
  methods: {
    onValueChanged(evt) {
      console.log(evt);
    }
  }
}
</script>
@alexanderbenavides alexanderbenavides changed the title [feature] "inputs", "selects" and others form elements does not work in vue3 in the same way [feature] "inputs", "selects" and others form elements does not work in vue3 like in vue2 Jan 19, 2021
@claviska
Copy link
Contributor

This happens because of a change in the way Vue 3 uses in-DOM templates. While this did work in Vue 2, even then they recommended using kebab-cased event names. From this page:

This rule aims to warn the custom event names other than the configured casing.

Vue 2 recommends using kebab-case for custom event names.

Event names will never be used as variable or property names in JavaScript, so there’s no reason to use camelCase or PascalCase. Additionally, v-on event listeners inside DOM templates will be automatically transformed to lowercase (due to HTML’s case-insensitivity), so v-on:myEvent would become v-on:myevent – making myEvent impossible to listen to.

For these reasons, we recommend you always use kebab-case for event names.

Unfortunately this isn't something Stencil can fix, and it was such a pain that it caused me to rework custom event names in Shoelace. 😓

FWIW, this isn't specific to Vue. Any library that uses declarative binding with in-DOM templates will run into the same problem.

Since converting all events to lowercase may not be feasible, there's an undocumented feature that Ionic uses to translate custom event names on the fly in the defineCustomElements() function.

await defineCustomElements(window, {
  ce: (eventName: string, opts: any) => new CustomEvent(eventName.toLowerCase(), opts)
} as any);

I hope that helps!

@claviska claviska transferred this issue from ionic-team/stencil-site Jan 19, 2021
@ionitron-bot ionitron-bot bot added the triage label Jan 19, 2021
@claviska claviska changed the title [feature] "inputs", "selects" and others form elements does not work in vue3 like in vue2 Custom Events with uppercase characters no longer work in Vue Jan 19, 2021
@jackchoumine
Copy link

I created an input in stenciljs and I have register a valueChanged event in there. Then I want to use the input in vue with the v-model directive. But the the event @valueChanged does not work in vue 3, but it does in vue 2.

Vue 3:

image

vue 2: image

My code in vue2 and vue3 are the same:

<template>
    <cb-input label="Name: " @valueChanged="onValueChanged"></cb-input>
</template>

<script>

export default {
  name: 'App',
  components: {},
  methods: {
    onValueChanged(evt) {
      console.log(evt);
    }
  }
}
</script>

same issue: stencil components events not working in Vue 3

@dmartinjs
Copy link

dmartinjs commented Nov 22, 2021

a small "fix" when waiting a fix from Vue 3

// Apply polyfills and declare components
applyPolyfills().then(() => {
  defineCustomElements(window, {
    ael: (el: any, eventName: string, cb: any, opts: any) => el.addEventListener(eventName.toLowerCase(), cb, opts),
    rel: (el: any, eventName: string, cb: any, opts: any) => el.removeEventListener(eventName.toLowerCase(), cb, opts),
    ce: (eventName: string, opts: any) => new CustomEvent(eventName.toLowerCase(), opts)
  } as any);
});

this will lowercase all your events,
it will work for directives (@listen and @event ) but will not modify manual addEventListener be aware of that.

Since this problem is for all web components and not only Stencil, I don't think the Stencil team can do something about it.

this issue is referenced in the Vue repo (vuejs/core#2460).

@zh3ngyuan
Copy link

zh3ngyuan commented Feb 23, 2022

a small "fix" when waiting a fix from Vue 3

// Apply polyfills and declare components
applyPolyfills().then(() => {
  defineCustomElements(window, {
    ael: (el: any, eventName: string, cb: any, opts: any) => el.addEventListener(eventName.toLowerCase(), cb, opts),
    rel: (el: any, eventName: string, cb: any, opts: any) => el.removeEventListener(eventName.toLowerCase(), cb, opts),
    ce: (eventName: string, opts: any) => new CustomEvent(eventName.toLowerCase(), opts)
  } as any);
});

this will lowercase all your events, it will work for directives (@listen and @event ) but will not modify manual addEventListener be aware of that.

Since this problem is for all web components and not only Stencil, I don't think the Stencil team can do something about it.

this issue is referenced in the Vue repo (vuejs/core#2460).

I am using @stencil/core@2.14.0 seems like there is no property ce defined in CustomElementsDefineOptions in this version, I was wondering if there is any workaround for it?

Update: seems like the CustomElementsDefineOptions defined in loader/index.d.ts doesn't not include this property but we can still use it

@bjankord
Copy link
Contributor

bjankord commented May 2, 2022

Just ran into this issue. Going to be updating all of our custom events from camelCase to kebab-case so they work with Vue 3. I think it would be good to update Stencil's event docs to use kebab-case as well:
https://stenciljs.com/docs/events

@jeco123
Copy link

jeco123 commented Oct 20, 2022

Have you tested the v-model feature with this "hack" ? on my side, nothing happens with the v model directive

@tanner-reits
Copy link
Member

Hey all 👋

Based on the conversation, it sounds like this evolved into more of a support request/topic as it falls outside Stencil's scope. As such, I'm going to get this labeled and closed out appropriately. Hopefully everyone was able to work around the issue within Vue!

@tanner-reits tanner-reits added ionitron: support This is a support question and removed triage labels Feb 16, 2023
@ionitron-bot
Copy link

ionitron-bot bot commented Feb 16, 2023

Thanks for the issue! This issue appears to be a support request. We use this issue tracker exclusively for bug reports and feature requests. Please use our slack channel for questions about Stencil.

Thank you for using Stencil!

@ionitron-bot ionitron-bot bot closed this as completed Feb 16, 2023
@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ionitron: support This is a support question
Projects
None yet
Development

No branches or pull requests

8 participants