Vue: Add a way to check if a component responds to an event, or make vm._events public

Created on 4 Sep 2018  路  12Comments  路  Source: vuejs/vue

What problem does this feature solve?

It would be nice to be able to check if a component responds to a given event or not. We can already do so for listeners declared in the template through the vm.$listeners object, but the ones registered with vm.$on() / vm.$off() don't show up in this object, they are stored in the private vm._events object.

I would like to suggest to either add a function that checks if a component responds to a given event, or to make vm._events public, and call it vm.$events

What does the proposed API look like?

A method called vm.$responds(event) could be considered, returning true if a component responds to a given event, false otherwise. If an array of strings is passed to this method instead of a string, it could return true if the component responds to some of these events.

Alternatively, the interface could simply be vm.$events

feature request

Most helpful comment

@lehni just saw that you are behind Paper.js. 馃槏

I regularly play with the Voronoi example because I noticed that it calms me down and helps me relax. If you are in the area ping me for a beer/coffee/whatever :)

All 12 comments

What is the use-case behind?

It's to permit an optimisation that only builds a larger parameter object for a given event if the event is actually to be received by the component on which it is emitted.

As you explained yourself, for parent/child events, you can already$listener, so I think @posva is interested in understanding what use case requires to emit and listen to an event within the same component, instead of, for example, calling a method if someCondition: true is set in the component's local data.

It's not something I've ever come across so far.

The reason for asking for the use case is this: Adding a new API for the purpose of a "fringe use case" isn't really anything we would consider right now, so we have to understand the prevalence and severity of the use case(s) for any new API/feature we add.

@LinusBorg I am not listening to the event from the same component. I am simply listening to this event programmatically through a call to $on(), instead of directly from the template. And when doing so, the event doesn't show up in $listeners, only events that are provided in the template do so.

This is something I am using in @ditojs/admin: https://github.com/ditojs/dito/tree/master/packages/admin, a Vue.js based framework to build admin UI from simple Pojo schemas. And since much of the connecting is happening through code and processing of these schema, i cannot listen the vents in a template.

Since one is exposed, I was wondering why isn't the other.

Oh, the use case was clear to me: you don't want to emit if the component isn't listening to the event because building the payload for the event is expensive

Since one is exposed, I was wondering why isn't the other.

$listeners didn't exist until Vue 2.3 or something, it was added after a lot of people asked for it, it's useful, for example to pass down listeners like you pass down props - which happens a lot in functional components and HOCs.

OTOH, no one asked for what you asked for so far, so we didn't think of adding it. No need for an API that nobody wanted so far.

. And since much of the connecting is happening through code and processing of these schema, i cannot listen the vents in a template.

A quick search didn't bring up any use of $on in the codebase (github code search ignoring special chars is no helping), care to link to one?

Just an idea: instead of emitting the costly object you could emit a function that, when called, returns the costly object. Then the costly object is only ever created when someone actually calls the function you emit which in turn should only happen when someone is listening to your event. Just my two cents. Not sure if this any good though. 馃榿

@ChristianKienle a good idea, but this is for a public-facing API, and I'd like to use a similar approach as Nuxt does for its hooks, where you use destructuring to pluck the parameters that you need out of one single object argument provided to the callback...

In the meantime I've transitioned fully away from Vue's own event mechanism, since I needed the callbacks to be async and also queued. I guess we can close this issue, but maybe $responds() would still be useful to others? Here's my EmitterMixin: https://github.com/ditojs/dito/blob/master/packages/admin/src/mixins/EmitterMixin.js

@lehni just saw that you are behind Paper.js. 馃槏

I regularly play with the Voronoi example because I noticed that it calms me down and helps me relax. If you are in the area ping me for a beer/coffee/whatever :)

@ChristianKienle ha that's nice to hear, thank you! Actually, @puckey is the author of that example, he'll be happy to hear that I'm sure.

Was this page helpful?
0 / 5 - 0 ratings