core: [Vue compat] @click not working on a component
Version
3.2.11
Reproduction link
Steps to reproduce
Clicking on “click mee”
What is expected?
Should log “click” in the console
What is actually happening?
Not doing anything
I tried adding COMPILER_V_ON_NATIVE: false to vue.config.js but it seems to make no difference. This issue only happens in the compat build of vue
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 22 (7 by maintainers)
Commits related to this issue
- Provide information about parent-child migration As described in this GitHub issue comments: https://github.com/vuejs/core/issues/4566#issuecomment-917997056 and suggested as a useful addition ... — committed to sfreytag/v3-migration-guide by sfreytag a year ago
- FIx for parent event handlers not being attached to the b-table element. It's a complex issue with @vue/compat, see https://github.com/vuejs/core/issues/4566#issuecomment-917997056 — committed to XactSystems/b-pagination-table by ianef 2 months ago
So I’ve been looking into this, and it doesn’t really qualify as a bug. Rather, it’s a complicated interaction between multiple breaking changes and their corresponding COMPAT flags/behaviors. This might need a special entry in the migration docs.
Short summary
.native, we do emulate this by passing a flag along the event to the child component which can then properly handle the “native” event..nativeanymore, we pass the event like a normal component event listener to the child (no additional flag).Solution
In the child component, the following
compatConfighas to be set:This has the following effects:
this.$listeners(Vue 2 API, not present in Vue 3)emits: []option are added as native listeners to the template root element. (new Vue 3 behavior)If the child is already fully migrated and can run in Vue 3 mode, the problem would also be solved:
Concerning Migration documentation
So this is one of the most complex migration steps in fact, as it involves a change in behavior in the parent and child interaction.
.native..nativeremoval$listenersremoval and non-declared events now being part of$attrsemitsSo what would be a good migration strategy that we can document? I think this would be good
.nativein templates until the children are ready to handle native events in the Vue 3 way$listenersto use$attrsinstead (usually used in combination withinheritAttrs: false)emits: []INSTANCE_LISTENERScompat behavior.native/cc @vuejs/docs
You need to use the
.nativemodifier.Yes, however, it is not explicit that only the flags that are prefixed with
COMPILER_will work in the build setup and not the other flags that are not prefixed with it. This is what is confusing.On the Compat Configuration section, it defines 4 different places you add these flags. It doesn’t offer any real explanation as to the purpose behind which one should be used, why and when it would make sense to use one over the other (as in this issue’s case).
Instead, the guide comes across as “provide these flags where ever you want”. So, when I follow the installation in the guide for
vue-cli(which already hascompatConfigin thecompilerOptions) and my immediate thought is: “Oh! I can just put any compat flags here.”Which is what I did and why I couldn’t get it to work prior to finding this issue. That is what I meant by “adding more details around where to put
INSTANCE_LISTENERS”:Adding a simple and general disclaimer on the guide that there might be times where you may need to add these flags specifically to components to get them to work properly.
I fixed my issue by adding INSTANCE_LISTENERS: false as suggested 😀
Thanks for the clear explanations Linus.
We had the issue while migrating to ElementPlus through the compat build, and we fixed it like this:
Then we can still prevent unwanted form submissions this way: