vuejs / rfcs

RFCs for substantial changes / feature additions to Vue core
4.85k stars 549 forks source link

Add a '.noinherit' modifier #578

Closed jez9999 closed 9 months ago

jez9999 commented 1 year ago

What problem does this feature solve?

Vue always tries to make a child element's root element auto-inherit an attribute or event listener if it's not explicitly defined in the child with props or emits. There should be a .noinherit modifier which prevents this behaviour, in case the parent doesn't want the child to inherit the attribute/listener and only wants it to apply if the child explicitly deals with it.

In addition, if the child has multiple root-level nodes, this will prevent the "Extraneous non-emits event listeners" warning from appearing. This is particularly useful when applying an event listener to a router-view, which becomes one of many different rendered routes, some of which may emit a particular event and some of which may not. Without a .noinherit, every single component with multiple root nodes that may be rendered by the router needs to be examined for every event listened to and either given inheritAttrs:false or explicitly defined as emitting that event, even if the component actually has no intention of emitting the event, in order to avoid the warning. For instance, in the following App.vue template:

<template>
    <router-view @displaymodal="handleDisplayModal" @displaypopup="handleDisplayPopup"></router-view>
</template>

... every child component that might get rendered by the router-view would have to explicitly not inherit attributes, or explicitly define displaymodal and displaypopup as emits, to avoid the warning. What App.vue really wants to say is "if the child emits this event, handle, but if not, do nothing, and don't give a spurious warning".

What does the proposed API look like?

    <router-view @displaymodal.noinherit="handleDisplayModal" @displaypopup.noinherit="handleDisplayPopup"></router-view>
Shujee commented 9 months ago

This is an annoying little thing that keeps cluttering the console during debugging. Hope someone could look into it soon.

posva commented 9 months ago

"if the child emits this event, handle, but if not, do nothing, and don't give a spurious warning".

The warning is there to help people find problems. In this case, it warns because it's applied to too many components (all existing pages) so it's normal for it to appear more than it should.

Adding a modifier to remove a development warning would be problematic as .noinherit still reflects the same behavior as inheritAttrs: false but for a single attribute, creating other inconsistencies and confusion down the line as people might erroneously use the modifier to silence a warning they should have instead adressed.