Check out a free preview of the full Introduction to Vue.js course:
The "Communicating Events" Lesson is part of the full, Introduction to Vue.js course featured in this preview video. Here's what you'd learn in this lesson:

Demonstrating that if any changes occur on a prop, problems may occur as the parent would override that prop's value when it is re-rendered, Sarah introduces the $emit option as the way to make sure the child updates the parent regardings its updated value and makes components re-usable throughout an application.

Get Unlimited Access Now

Transcript from the "Communicating Events" Lesson

[00:00:00]
>> Sarah Drasner: All right, communicating events. So far we've been passing down static values down to from the parent to the child, or we've been binding dynamic values. But sometimes we need to do more things than that right? Sometimes we need to actually work with events and event handling. So if we have something like this Vue component.

[00:00:21] We have, it's just called child, cuz I'm really good at naming. [LAUGH] And the template is called child as well. And we have this Vue instance, which we say, if we have a method that says talk to me, we have this.text. And it says, forget introductions, I want a taco.

[00:00:38] We have our app, we have our text and message, you should be used to this one. We saw that one earlier but now we have this child. And in the child, we have the text, and also click talkToMe. So let's go look at this in CodePen again. And we can collapse these values.

[00:00:55] So when we execute, actually I'll even go one further. When we execute this, we can do that but in our console, we're gonna come up with this warning. And this warning is a very, very important warning and Vue is absolutely right. If we're mutating that prop directly then what's going to happen is that won't tell the parent that something changed.

[00:01:21] So you're changing it on the child, but you're actually not managing that data well, because then you've got two different things going on. You've got the child instance, and the parent instance is still the same as it was before. Let's go look in the Vue devtools, we'll go to child that says forget introductions.

[00:01:38] But this one still says, 'hello mr magoo'. That's not good, that's a place where things are deviating from each other, and we don't want that. Remember props are always from parent to child communication. It's going down, it's not going back up again. So how do we make that work then?

[00:01:56] What we can do is we can take our component and we can make a special event handler. And if this doesn't make sense to you, don't worry we're gonna go into depth in the next slide. We're gonna use a thing called $emit. This dollar sign means that it's a special option that Vue is granting us.

[00:02:12] And that $emit is really nice because what it does is report its activity to the parent, and it's really very flexible. So you can have this myEvent and then when you're calling myEvent, you can also pass in values. You can pass in more than one value if you have a bunch of values.

[00:02:34] So we're gonna zoom in here. So previously we had this.text= 'forget introductions, I want a taco', this is what we had before. And we had this HTML that had the text and talkToMe Let's talk. So what will we need to change? Well the first thing we would need to do is we would need to say this.$emit changeText or whatever you want your thing to be called.

[00:02:59] It could be called anything, and we're gonna pass this.text, cuz that's the thing that we're changing here. And then in the HTML we're going to add an event listener that at, but it's not mouse move, it's not click or something. It's this changeText that we had said from the $emit, so that could be called anything.

[00:03:24] I could call it Taco Bar, and it would be at Taco Bar down here. So that's corresponding to, these two are kind of communicating to each other. In this instance what we´re saying is, message is going to be $event. That $event is an option that´s available to us through the Vue instance.

[00:03:49] So let´s see it in action. We now have this.text = 'forget introductions, I want a taco' this.$emit{ changetext, this.text.}. And then when I, let's go to our HTML here, we've got that changetext message is event. And now when we do this, let's go look at our console, now when we do this, we, no, that should not be.

[00:04:27] We are omitting it, sorry I think I messed up something here. I have this data property so that we could see it changing. Now it's actually updating that data, let me look in the Vue Dev tools. 'hello mr magoo', let's talk.
>> Speaker 2: Do you still want to change text in your components or do you just omit what the new text should be?

[00:05:01]
>> Sarah Drasner: I think we're just omitting what the new text should be. This is, according to the doc should be okay.
>> Speaker 2: You're actually using the [INAUDIBLE]. Yeah you're still changing.
>> Sarah Drasner: Yeah that's true, actually so there is another way that we can do this, sorry. This might not be actually the correct way of doing this.

[00:05:19] So if we want to use a method instead, this will actually work better. So we have this method, and we have this ball that's bouncing with an SVG and it's bouncing. And we can increase the height and it gets bigger as we're increasing the height and it'ill keep bouncing and stuff.

[00:05:41] And I can reset it and start it again. And this is passing this increase height through that event. So what we're doing here is we've got this increased height, and we've got this $emit and height increase. So in our button which is a component, we have @click= 'heightincrease' and in the methods we have this function where we're $emitting 'heightincrease'.

[00:06:11] The interesting part here is that, well actually let's go through more of this code. So we've got @click='heightincrease' that we're increasing the height. We've got animateBall and we've got @heightincrease='incrementheight' and then on the child we are $emitting that. So on the parent we're just basically using this height-counter, and it doesn't do much, it just increments the height.

[00:06:36] But the interesting part is that these don't, what is happening on that child, the events that we're using on that child, don't have to be the same as that parent. So when we look at the parent, what we're doing is we're taking that total, and we're incrementing this.total, because this heightincrease is executing.

[00:06:56] So it's just alerting that something is changing, between one component and then other, It doesn't have to be the same.
>> Sarah Drasner: So now we can do something like this where we have multiple components, and we have Increase height, and Increase radius. And we can start and we can increase the height and increase the radius as it goes, we can restart it.

[00:07:25] So if we have this.count, the counts start at 3 but you could see that we have that total starting at 200. That total is incrementing this.total by 100 every time we execute it. So these aren't even actually the same values. We can have a completely different logic for the child and the parent if we want to.

[00:07:48] We're just letting it know that something was happening between those two.
>> Sarah Drasner: So in the children we have heightincrease and radiusincrease. And in the parent we have heightincrease and radiusincrease, and then we're calling incrementHeight, incrementRadius. We have a relationship between @click heightincrease, and then that @click on the parent is going to be executed the same way.

[00:08:17] Then we have this height-counter, we're saying that that ID becomes the heightcounter. So that becomes the component here, and then that radiusincrease is @click radiusincrease, and @radiusincrease. So if we have something like this backpack, like we saw earlier, we have this component that's updating. And that's nice and all, but maybe we don't wanna just have a component that has one thing, that doesn't look like a normal store at all.

[00:08:47] So what we would actually have is something where we're using multiple components and we have multiple components in a store. So we have this one change in quantity, this one change in quantity, and this one change in quantity. And if we look back at the code here we can see that we have tese items and the URL and the props and the child using this template of child.

[00:09:15] And then we're increasing the counter the same way. So these kind of components are really nice to use for something like a store. You can keep reusing them with different things that you're passing down.
>> Sarah Drasner: So in the app itself, we have this manifest file, that has the backpack, the URL.

[00:09:34] And then the child item we're passing down the unit.item, unit.url and the component itself, we have that item.
>> Sarah Drasner: So that's really, really nice for reusable components