question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

should vuejs2.0 keep the $broadcast, $dispatch event api? No good solution to address point to point parent-child communication in 2.0

See original GitHub issue

@yyx990803 , Hi, vuejs core team, I am struggling on find a good solution for point to point communication between parent child components with vuejs2.0. Because vuejs2.0 has deprecated the $broadcast,$dispatch api, it is very hard for me to find an alternative solution $broadcast,$dispatch provides with vuejs2.0 event bus feature. I have written a thread in the forum about this topic here, and I’d like to paste it here for more discussion.

PLEASE DO NOT CLOSE IT UNLESS have a good idea or solution on vuejs2.0. Thanks~!

<pcom id=1>
    <soncoma></soncoma>
    <soncomb></soncomb>
</pcom>
<pcom id=2>
    <soncoma></soncoma>
    <soncomb></soncomb>
</pcom>

In above code, when child of pcom1, for example, soncoma $emit a event, say,

bus.$emit('son-coma-event',somedata)

on the pcom, we listen that event with

bus.$on('son-coma-event',function(){})

I only want pcom1 will handle that event, but unfortunately pcom2 will also handle that. How to tackle this condition?

One of the workaround in my application is to use the this.$parent as event bus In child:

this.$parent.$emit('some-event',someData)

In parent:

{
   created(){
       this.$on('some-event',function(){})
}

The negative point for above workaround is:

  1. we couple a lot on the parent-child relation;
  2. it does not work if there is more in-depth level of parent-child levels;

In some more complex conditions, it will be more difficult to find a good solution for the custom event system, for example, a recursive component

 <pcom>
    <recursivechild>
             <recursivechild>
                          <recursivechild>
                          </recursivechild>
             </recursivechild>
    <recursivechild>
</pcom>

 <pcom>
    <recursivechild>
             <recursivechild>
                          <recursivechild>
                          </recursivechild>
             </recursivechild>
    <recursivechild>
</pcom>

how recursivechild communicate to its direct pcom component? Please give your idea or point on these topics. Thanks~!

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:41 (21 by maintainers)

github_iconTop GitHub Comments

3reactions
rhyekcommented, Oct 1, 2016

Copy/pasting my own comment from another issue: https://github.com/vuejs/vue/issues/2760#issuecomment-250883407

I think removing $dispatch was a terrible idea. This wasn’t the first ui framework/library to implement the notion of bubbling actions/events up a visual tree. It’s a well established idea. Why take away this functionality on the premise that " being able to dispatch a event that causes side effects in its unknown parent tree sounds like a recipe for trouble to me"? You need to leave this responsibility to the users. I’m sure most have the common sense to use this feature appropriately. It is not a new concept!

I really can’t see the benefit of this change when this library is built upon long time established web technologies/concepts such as the DOM and DOM events that do in fact bubble up the visual tree and have been doing so for years with no one complaining. Isn’t the idea of components something that has been recently embraced thanks to the W3C proposal for web components? In my opinion, It only makes sense that Vue components behave similarly to regular DOM elements in regards to how event handling is done.

The proposed alternative to use a global event bus seems illogical to me when something more practical, effective, and easier to understand (due to it being a well established concept for years) already existed.

Other proposals in this thread remind me of how EmberJS wants to do it. Passing closure actions as properties to the components down each level of the hierarchy. So tedious and unnecessary! Vuejs was the reason i wrote https://www.npmjs.com/package/ember-component-action-bubbling!

Aside from this, I really like your library. But seriously, I think this was a terrible change.

2reactions
LinusBorgcommented, Oct 5, 2016

@rhyek I would like to give my 2ct about a couple of points you raised. Since the discussion has already brushed a number of topics, I would like to get back to the basics about why we deprecated $diospatch and $broacast:

1. implicit coupling.

If you have a parent and a deeply nested child that dispatches an event, there’s no way to infer this relationship from the code (and the same is true for $broadcast, oviously.)

If you look at the other changes and deprecations we introduced with Vue 2.0, you might realize that removing implicit behaviour in favour of explicit alternatives is a common theme, and deprecating $dispatch fits right in there.

Example:

// parent
events: {
  'some-event': function () { ... }
}

// deeply nested child:
$dispatch('some-event')

This is fine when the parent only has one direct child - but in that case, $emit() with a listener in the template is no real extra work, either.

It becomes hard to follow (especially in teams) as soon as you have nested children (especially deeply nested), or even more than one direct child - you either have to look through all children, or rely on code comments to document which event is tiggered from which child component - which is additional boilerplate, as well.

You say that you like $dispatch and $broadcast because you don’t have to pass them through other components. And I can agree that it’s easier - but we have not come across many situations where this was actually nessessary, or rather: if there was such a chain of passing up an event, it would rather be the case that the data would be changed/appended/ during this trip by component in between.

2. Event names

when you use $dispatch with deeply nested components, you would have to be very explicit in namespacing your events, because otherwise, they could be clashing:

// parent
events: {
  'close': function () { ... }
}

// deeply nested child 1:
$dispatch('close')
// deeply nested child 2:
$dispatch('close')

…and if those children are third-party-libs, your screwed now. or have to catch the event in some component in the middle just to rename it before you $dispatch() further up to the parent. And don’t forget to comment this, because someone looking at this code might think why you do nothing other with an event than renaming it.

Using $emit and template listeners does not have this problem. you can use simple, short event names everywhere, they won’t clash as each event has it’s own callback attached in the template @close="callback".

I really just wish you didn’t take away the *choice * to use either paradigm,

If we thought both paradigms can work equally well, we would treat them equally. But we don’t think that, for the above reasons and more.

Therefore, we try to steer users to the pactices we found to work best, while leaving a way to get around it with the “global Bus” method.

I would also like to talk about your worries about global state, but am not sure I understand your position fully yet.

Maybe you can provide an example where you think $dispatch and $broadcast work best for you, and I try to show you how “our” approach could improve the situation?

Read more comments on GitHub >

github_iconTop Results From Across the Web

VueJs 2.0 emit event from grand child to his grand parent ...
Another solution will be on/emit at root node: Uses vm. ... For passing data from deep nested child, to not directly parent, communication....
Read more >
Vue.js Parent/Child Communication (Broadcast or Dispatch)
Currently I have the parent component pulling the data from the database, then broadcasting and event (and passing the data) to the child...
Read more >
Vue 2 props and emit - parent to child | by Kevin Hu - Medium
Vue will not trigger the checking function. Parent and child will share the value, point to the same address. They will change at...
Read more >
vue disabled multiple conditions - You.com | The Search Engine ...
vuejs/vueshould vuejs2.0 keep the $broadcast, $dispatch event api? No good solution to address point to point parent-child communication in 2.0#3581.
Read more >
Vue JS 2 Tutorial #24 - Events (child to parent) - YouTube
Hey gang, in this Vue JS tutorial I'll introduce you to events, and how we can use them to pass data from a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found