emits property blocks $attrs injection
Version
3.2.19
Reproduction link
Steps to reproduce
Having a component that both declares emits
because it itself emits an event (see Mid
component in sandbox) and that also expects to pass down onMyEvent
down as $attr fallthrough to a Child
does not work.
The emits
option effectively makes the onMyEvent
attribute disappear from $attrs, and the chain is broken.
What is expected?
emits
property should not remove onX
from $attrs
What is actually happening?
It gets removed and breaks attribute event inheritance
There's a workaround by defining the event in props
instead of emits
:
<template>
<div>
<Child v-bind="{ ...$attrs, onMyEvent }" />
<button @click="$emit('my-event')">Mid emit</button>
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
//emits: ["myEvent"],
props: {
onMyEvent: Function,
},
inheritAttrs: false,
components: { Child },
};
</script>
The cleaner solution would likely be to provide a way of accessing the events that were declared with emits
. They should not be part of $attrs
, IMHO, as the default usecase of $attrs
is to access anything that was not declared in props/emits.
Thanks @LinusBorg that's a nice workaround! Hopefully, we can get a proper solution 🙏🏻
I agree with you that $attrs
should not include it as it does feel like the magic box of "everything else".
To document another workaround, explicitly listening for and then re-emitting the event also works.
<template>
<div>
<Child v-bind="$attrs" @myEvent="$emit('myEvent')" />
<button @click="$emit('my-event')">Mid emit</button>
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
emits: ["myEvent"],
inheritAttrs: false,
components: { Child },
};
</script>
This behavior is expected (https://github.com/vuejs/rfcs/pull/154#issuecomment-614724480) so it should maybe be documented instead.
This is a duplicate of https://github.com/vuejs/vue-next/issues/3432, #4736, #4489.
Given https://github.com/vuejs/vue-next/issues/3432#issuecomment-812237075, this should go into a discussion in the rfcs repo with a proposal to enable $attrs
still have the listeners that are declared in emits
. Maybe a new option similar to inheritAttrs
to explicitly state that $attrs
should also have listeners declared in emits
.
You can find a well-described example of how to handle this in this reply by @LinusBorg
@marina-mosti can you open a new discussion in the rfcs repo?
As suggested, discussion open here: https://github.com/vuejs/rfcs/discussions/397