Allow components to listen to <slot> events
See original GitHub issueWhat problem does this feature solve?
I’m aware this has been discussed previously -
- https://github.com/vuejs/vue/issues/4332 and
- https://github.com/vuejs/vue/issues/4781
- https://forum.vuejs.org/t/listen-on-events-when-using-slots/2519/7 (no resolution here)
Neither of which seem to lead to a solution that allows me to not tightly couple two not-necessarily related components.
I’m trying to use a datepicker component inside a datatable component as a filter, and there can be a dynamic number of datepicker components depending on what data we’re piping into the datatable. I’m also integrating this into an existing (large) codebase so I’m trying to keep all the state local to the components (no Vuex or global Vue data at all).
Ex.
<datatable api-endoint="/api/v1/orders.json">
<datepicker filter-on="signupDate" title="Signed Up"></datepicker>
<datepicker filter-on="lastActiveDate" title="Last Active"></datepicker>
// etc
</datatable>
I’d love for this datepicker to be a generic date picker that can emit a “data-selected” event with the date the user selected and then wherever it’s used in the application the parent can simply listen for the event and take action (in this case re-querying the data with a date filter). Right now I have to tightly couple the datepicker to the datatable component to fire off the datatable’s filtering.
I’m just not sure I’ve seen a coherent argument for not allowing the parent to listen for the events.
What I’ve seen as a response seems to be singularly that slots won’t necessarily be a single element, but why’s that an issue?
It can end up rendering anything: text, plain element, multiple nodes… the behavior will be unpredictable.
and
As explained in #4332, it doesn’t make sense to add listeners on <slot> because <slot> doesn’t always render only a single element.
It should be no different than in Javascript with addEventListener
that can be triggered from any number of child nodes.
What does the proposed API look like?
Allow a component with a <slot> to listen to events emitted from that <slot>
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:17 (6 by maintainers)
Top GitHub Comments
Thanks for your interesting. However, nothing changes regarding existing arguments. An event is always bound to a single element/component. To me, it looks like what you need is to pass a function in a scoped slot and let the parent use that function, but your example is unclear. That could be done like this:
Could you clarify what is exactly problematic, or what are you trying to write in your template?
Hey @theianjohnson, you can use Provide/Inject to provide some of the event handlers inside the
<datatable>
component that can be later injected into<dateFilter>
component. Or any child components that chooses to inject those methods.This might not be the solution you asked for, but at least it does not create a strong coupling like
this.$parent.$emit
. And with proper documentation, it’s pretty easy to manage.Here’s an example: https://codesandbox.io/s/nny1m3j1j
As for event bubbling – events that are not caught by a parent bubble up to the root component. If for some reason you have another handler for the same event name – you’re in trouble. Makes it also much harder to see explicit connections, especially if the component tree changes so that a component is no longer an ancestor/child of a specific component.