Check out a free preview of the full Vue 3 Fundamentals course
The "Event Handling & View Model" Lesson is part of the full, Vue 3 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Ben demonstrates handling events in Vue, defining methods, and using the v-on and v-bind directives to call those methods to add interactivity to the page. The v-model directive can be used in place of v-on and v-bind to create a two-way binding.
Transcript from the "Event Handling & View Model" Lesson
[00:00:00]
>> Okay, so we've learned how to create an app, we've attached some reactive data. That was fun, hopefully, pretty easy to do. And now, of course, we wanna talk about how we deal with user input, right, cuz that's what a lot of JavaScripts value is. It's handling the interactivity of your website.
[00:00:13]
So the first thing we wanna talk about is let's open Playground actually in Chrome, so we have that. So let me just open a new tab with this, and this will be Playground. Okay, so for the sake of Playground demo purposes, let's just use the standard example of the Counter app, right?
[00:00:34]
Which is the fact that if we go inside of here, and this time, I'll see, let's do that sequentially. So I'll put a horizontal line here, line break, there we go. And then here we'll just do an h1, we'll call it Counter. We have a count, and then we have a button, where we want to increment count.
[00:00:51]
This should look pretty familiar, 10. Okay, so if you scroll down, I don't like the fact that this is all the way at the bottom. I'm gonna actually move this up to the top. Copy that, and hr, great, so we'll do this from most recent to oldest. Okay, so here we have our counter and your question is probably thinking, okay, how do we actually change data?
[00:01:16]
Because after all, it's fun to render some reactive stuff, we wanna do more with it. So inside of Vue, we have our data here, but the question is we wanna actually change it. And so the option that we wanna learn about next is the concept of methods. And so if we think about functions in JavaScript, right, typically, we would have something like let count = 0.
[00:01:38]
And then you'd have a function called increment, and it would say count ++, something along these lines. When you think of methods, think of it as functions from JavaScript that are available for your app to call it anytime, that's the best way to think about it. So from this perspective, we would actually want to then define a method, we'll just say incrementCount.
[00:01:59]
And inside of here, this is where a question that we had earlier comes into play. So when you wanna refer to something else in the app, so in this case, we wanna actually refer to this count property inside of data. Vue is smart about a lot of things, but if we just currently say, count++, this is not gonna work.
[00:02:21]
And the reason for that is because if we know as when it comes to JavaScript in programming, scoping is a thing. So it doesn't know basically where to fetch count from, and so this is where the dreaded keyword of this comes into play when it comes to JavaScript.
[00:02:35]
That this keyword is where Vue basically takes the context of the app, and it will basically figure out where count exists. So from Vue 2, you might have noticed it from like this.data.count, this would be an explicit thing you might do. But because Vue knows that oftentimes we're referring to data or computed unless you have some really clear name clashes, you can just use this.whatever property you're looking for.
[00:02:57]
And that goes for basically anything you're defining within this Options API. And the benefit of this is that while some people find that this keyword is confusing, the point of it, I think at the time when the API has been designed is around the fact that you shouldn't really have to think about what this even means.
[00:03:14]
The point is I think of this as the app, and that will you come in and you've referred to this app, and that's it. So when I was teaching other people Vue for the first time, even though they didn't have a lot of JavaScript experience, they got the convention that as long as I call this, it refers to my app.
[00:03:28]
And I'm not gonna learn about scoping or anything, it just works, and that in itself is an advantage from a learning perspective. But just know that you don't have to use this so that in the future, if people are actively avoiding it, we can go ahead and do that once we learn about composition API.
[00:03:43]
But while we're in the Options API right now, this is how we actually refer to things within this configuration object. Okay, so now that we have the this count++, what we're gonna do here now is we're gonna go set how do we actually call the thing? And so what we're gonna do is we're gonna just like before, we're gonna use a Vue directive to actually call the thing.
[00:04:03]
And so we're gonna use v-on, that is the directive that you'll want to learn for this. Because similar to what you know from JavaScript events, onclick, onkeyup, this is the same idea, we're extending on that theory. And so instead of just like onclick though, which you might think that's what I'm probably gonna guess, because Vue on itself is the directive, you have the ability to pass it an argument through the colon symbol.
[00:04:29]
So it's v-on: the event that you wanna call, and the event you wanna, again, is standard JavaScript events. We haven't made anything up, so key up anything that you can think of that's standard in the JavaScript API that exists. And so when you click, what do we wanna refer to?
[00:04:45]
Well, guess what, we wanna refer to our incrementCount function that we had earlier. The key thing here to remember though is that you don't want to actually call the function, because this is something that will be called when the event is triggered. So basically, you're passing a reference to the function inside of your app.
[00:05:01]
And then when it's clicked, it will be called, that's the reason why you don't call it immediately. So if we save that, and let's go ahead and now refresh our page. You can see, boom, things are actually changing and they're being tracked. So that's fairly straightforward. What about something a little bit more complicated like what if I wanted to set the amount that the counter is being incremented by?
[00:05:24]
Okay, well, in this case, you're gonna say, well, let's say we have a label here, let's say incrementAmount and then it'll be increment by. And then you probably have some elements here, that's a number. And then so if we refresh this, theoretically, what you would want is the ability to change the amount that increment count is changing.
[00:05:46]
So how would we actually do that? Well, first of all, what we wanna do is we need a reactive data property, cuz we wanna track what the heck is going on. So at this moment, if we go down into our data, we have this count. And we can say, we can just have incrementAmount, a reactive data property and currently, it's 1.
[00:06:05]
And then what we wanna do then is tie it into our incrementCount down here, so let me actually collapse this. And so rather than just incrementing it by 1, which is the ++, we'll do += this.incrementAmount. Oops, incrementAmount, save. And to show that this is working, I'm gonna switch this over to 10, and we're gonna go ahead and refresh this.
[00:06:29]
And you can see, it's jumping as you would expect by 10. But we want to be able to change this, right? How do we actually basically connect these two? So let me go ahead and actually wrap this part in the div real quick. Oops, that's not what I wanted at all.
[00:06:45]
[SOUND] div, there we go, okay, that should give it a new line, perfect. Okay, so the first thing first is we need our input to display what it is that value is. So how we do that? Normally, we would say value equals 10, this is standard HTML. But this is static, right, this is something we define ourselves, has nothing to do with our app.
[00:07:07]
How do we connect the two? The way we do that is with another Vue directive, because what are we doing, we're now extending upon our HTML to give it super power to do what? To have some interactivity, to be supercharged with reactive data. And so you do that via v-bind, right?
[00:07:22]
You're binding the value to a dynamic property, that's the way to think about it. But here though, what are we binding it to? We're not binding it to 10, that's not what we're binding by. We're binding it to incrementAmount. So we can refer directly to the variable that we talked about earlier.
[00:07:35]
And so to show that this change, this time, I'm gonna change incrementAmount to 8, and if I refresh, boom, there we go. We can see that they're now talking to each other. And so now, we can see when we increment count, this is great. It's actually changing, but what do we know about this?
[00:07:52]
We know that if we change now to 12, is it gonna make a difference? No, it's not, in fact, it's gonna reset itself back to 8. What's going on? Well, the reason for this is because you've told Vue, track this thing and make sure that its value is always bound to this incrementAmount, that's what you've told it.
[00:08:09]
And so this is why even though we've changed it once, and we try to increment the count, it's setting it back, because Vue is doing it's job that you told it to do. So what do we wanna do? We want to actually update incrementAmount whenever someone actually types inside of the input element.
[00:08:23]
Then. So how might you do that? Well, we're gonna actually listen to an event. And so what is that? We learned it is v-on, and we're gonna listen to the input event. And what we're not gonna do though is we're not gonna inline the function that will change this, because I find that to be very clunky.
[00:08:39]
So we're gonna call it changeIncrementAmount. And so what we're doing here is we're saying, hey, on the input event for this input element, when we get an input event, I want you to run this function, which we had not created yet to be clear. So come in here, and we'll go to the method and we'll say changeIncrementAmount just like that.
[00:09:02]
And here's the difference though. Now that you're actually listening to an event, you actually get a default event object that's passed to you once again just like you would expect from standard JavaScript. So I'm gonna call that event, and we're gonna do as though we're just gonna log the event to prove that this is working.
[00:09:17]
So I'm gonna go ahead and open this up, refresh. And if I go ahead and type in here or anything happening, look, the input event is being fired. So what do we know? Well, we know, again, we won't dive into the details of it, but event.target.value is what you're looking for.
[00:09:34]
That's usually the convention for when you're playing with form elements. So to show you this works, if I delete this, you can see it's actually showing up inside of my terminal as you would expect. And so now that we're actually getting the dynamic value of the event, we can then say, this.incrementAmount = event.target.value.
[00:09:57]
Now, to show that this works, I'm a big fan of making sure things are actually working correctly. So I'm gonna go ahead and inside of here, we're just gonna add a quick h1 for the incrementAmount. So you can see here, we're rendering the incrementAmount here and here. And if I change this now to 18, you'll see that it is being tracked correctly.
[00:10:19]
It's in here, and now we can increment the count, and then that's not working correctly. Anybody have a guess why?
>> String.
>> it's a string, that's right. So you might think, okay, well, you know what I'm gonna do, I'm gonna come in here. I'm gonna wrap this in a number, be done with it.
[00:10:36]
All right, let's refresh this to make sure that works. Let's do 80 this time, all right, that works, but I'll do you one better. Instead of having to come in here and do it here, which is kind of silly because the incrementAmount, it already has a target value.
[00:10:50]
And what's a bit odd too is that if we look at our input element, we are already type number. Why is that the case? Well, this is one way to fix it, here's the thing though. If we take a look at our inputs, Sam had made the joke that I showed in the tweet earlier that most of the web is rendering a list.
[00:11:11]
Well, I'd say a lot of the web is also filling out forms, right? I mean, that's what a lot of our bread and butter is too. So Vue was like, okay, this is a lot of work to do every single time you have a form element, right? Gosh, what if we could just learn from what Angular did and do two-way binding in this particular contexts?
[00:11:28]
[LAUGH] So instead of having to always define, and change, and track all this stuff, what if we had a directive called v-model and we tracked it directly to the data property that we cared about? Once you have this v-model, all of this I say disappears, but v-model is syntactic sugar for basically configuring all that underneath the hood.
[00:11:53]
Which means that inside of our method down here, we don't even need this as well, so I can save that. Now, if we refresh, once again, let's do 800 this time and increment. You'll see that things are changing just as you'd expect with this v-model. And what's even more interesting if you'll notice, it's not a string anymore.
[00:12:14]
Because once again, what Vue tries to do is it looks at the developer experience and it goes, hey, I know that I'm looking at an input element. Because here's the thing, V-model works with other form elements like checkboxes, radio, select, you can do all that. But it also knows what kind of input event to listen for, cuz you'll know that especially with select, that one's a tricky one.
[00:12:34]
I always have to look at the docs every time I work with select, I have to code it from scratch. But here, it actually knows that we are type number in here. And because of that, the value it's actually tracking inside of its app has automatically been converted.
[00:12:49]
Now, if we did string for example here or non string text revert, you can see, it's actually smart enough to know what to do. But [COUGH] the one thing I wanted to show because this used to be a Vue 2 thing is that you could actually attach arguments or basically modifiers to your directives.
[00:13:11]
So in this case, it's a V-model of number for example, but there'll be other opportunities I get to present that later on.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops