v-model Recap Example 0:00Okay, let's move on to custom inputs. I think you'll get a lot of use out of this. But first, an example. So you're familiar with vmodel at this point, right? So if we were to say, give me a text input, and we're going to set a vmodel to something like a coupon code. Okay, so very familiar to you at this point, right? Let's go to our app.js file, and we will bind that coupon code to something like freebie. All right, let's take a look in Chrome. And there we go.All right, let's take a look in Chrome. And there we go. We've found the value. So I have Vue DevTools installed, of course. So we can see that, yes, we have our coupon. It is bound to the input. And of course, if we were to change it, because we have the two-way binding, that is reflected in the input. This is all a quick recap. But what you may not know is that what you see here is just a syntactic sugar for doing v-model Longhand Breakdown 0:42This is all a quick recap. But what you may not know is that what you see here is just a syntactic sugar for doing this. Just think about it. If you use vmodel, it sounds like we need to bind a value to the input, and then we also need to listen for when the user types into the input and update the value, right? So there's two steps here. We bind the value to the coupon code. So now if we were to come back and refresh, we get the binding here, but we don't have any event that gets emitted.So now if we were to come back and refresh, we get the binding here, but we don't have any event that gets emitted. So that means if you do update the input, you'll see that this value does not get changed. And we would expect that, right? But let's listen for the input event. So when the user is typing into the input, we are going to update the coupon property right here equal to whatever the user has typed in. And as we've learned in previous lessons, we can use the event object for that. So just get the value of the current input. Okay, so this is equivalent to this.So just get the value of the current input. Okay, so this is equivalent to this. It's just naturally much nicer to write. But yeah, let's check it out. So we have freebie, we type into it, and now we get the two-way binding. We update this, coupon changed, exact same thing as we had before. So this is good to know. When you use vModel, it essentially translates to this. Bind a value and then listen for an input event and update the value. Okay, very interesting. Why Use Custom Inputs 1:59Bind a value and then listen for an input event and update the value. Okay, very interesting. But now what if we want to use it with a custom input? For example, maybe rather than something like this, you have some validation, you have some behavior, and you'd like to wrap that within your own coupon input. Or maybe you have an age input that gets used on your site, and again, there's some validation associated with that. In those cases, it can be really useful to give them their own input, and that way you don't have to reproduce all of that logic and validation and sanitizing, right? So if we're going to do coupon, vModel, well, it's not going to work exactly the same. Building Custom v-model Component 2:26don't have to reproduce all of that logic and validation and sanitizing, right? So if we're going to do coupon, vModel, well, it's not going to work exactly the same. We can give it a try though. So we're going to bind it to what we see here, all right? So it sounds like we need to set up a coupon component. And the template, we'll just do this inline here, will be an input with a type of text. But yeah, notice the distinction. It gets kind of confusing. We want to use vModel, so do we do the exact same thing here again? No, we don't want to do that.We want to use vModel, so do we do the exact same thing here again? No, we don't want to do that. Instead, we want to use this system right here because we already determined that they are equivalent. So let's do it. So we're going to bind the value of this input equal to the coupon code, and why don't we set a prop for that? So bind the value of the input to the coupon code, but then also listen for when the user types into this input, and we will update the code. And we're going to pass through the default value or the current value that the user hastypes into this input, and we will update the code. And we're going to pass through the default value or the current value that the user has typed in. Okay, so it sounds like we need a method for that, update code, and that will accept the current code. So now here is where you can do any sanitizing, any validation, any stripping. You can update the input, which we'll talk about in a moment, but also we want to make sure that we emit the input event exactly the way we talked about here. We have to emit an input event. This dot emit input, and then we're going to pass through the current typed code asWe have to emit an input event. This dot emit input, and then we're going to pass through the current typed code as its data. Okay, so let's give this a shot, but first, let's do the before and after. So I'm going to comment out where we emit the event, and we'll give this a refresh. Okay, so we can see on our root, here's where we've defined the coupon. Maybe it came from the query string, so like coupon equals foobar. That's contained in your root view instance, and then you pass it down to the coupon. But now as we type into it, we want to keep the two in sync. This is something you'll deal with when using view quite a bit, where you're always tryingBut now as we type into it, we want to keep the two in sync. This is something you'll deal with when using view quite a bit, where you're always trying to make sure that the two stay in sync. So as I type into our coupon input, you'll notice that on our root instance, the value does not change. They're no longer in sync. But now, we're going to emit the event, and you'll see that it does keep up to date. So we type into it, and there you go. That's exactly what we want. So we've essentially reproduced the model by using the long form version.That's exactly what we want. So we've essentially reproduced the model by using the long form version. Does that all make sense? Let's take a look. So we bind the value to the coupon code, then we listen for an input event, where we then can perform any validation like I talked about, any sanitizing, all that stuff. But ultimately, we emit the input event. So now, if these two are equivalent, it's just as if we said on the coupon component, listen for an input event, and then we're going to update our local coupon property. Exact same thing here, but obviously, this is much cleaner. Adding Validation and Reset 5:16listen for an input event, and then we're going to update our local coupon property. Exact same thing here, but obviously, this is much cleaner. Now, speaking of this, so yes, you could do sanitizing like trimming it, ensuring that it's of the proper type. You could also, maybe you have an array of expired coupon codes, and you just want to check to see, well, if they typed in one of these expired codes, maybe you perform an AJAX query, maybe you hard code it, whatever you want. But if that's what they type, then we need to notify them. So for example, maybe you have an old all-free code that's no longer relevant. Again, this can be dynamic in real life.So for example, maybe you have an old all-free code that's no longer relevant. Again, this can be dynamic in real life. But anyways, if that's the case, well, you would want to alert and say, this code or coupon is no longer valid, sorry, and yeah, that'll work. So if we type all-free, yeah, they get the alert message, but you'll notice that we still update our root instance. So it sounds like we want to clear things out. Now, what we could do is just return early, but I still don't think that's what we would want. So if we give it a refresh, all-free, we get the alert message.want. So if we give it a refresh, all-free, we get the alert message. But notice that we still synced it for every other key press up until that point. Does that make sense? So this is not all-free. This isn't, this isn't, this isn't, but this is. So now the coupon code that we sync is not what we want. So it sounds like we want to clear this out. Why don't we do this? Let's add a ref to this input.Why don't we do this? Let's add a ref to this input. Think of this as a quick identifier. We'll call it input. And that way I can say this.refs.input, I'm just going to set the value back to an empty string and then we'll return. Okay, so a little bit closer now. So if I type all-free, yes, we get the alert. Yes, we clear the input. But if we go to the root view instance, it's still equal to everything we synced up untilYes, we clear the input. But if we go to the root view instance, it's still equal to everything we synced up until that point. So it sounds like we still want to omit an event, but just update the code value. So why don't we do something along the lines of this and then not return. So if you type in the wrong coupon code, we'll let you know and then we'll reset everything. Okay, so that should do the trick now. All-free, sorry, you can't use that. We clear the input and then we emit the event, which resets the coupon code. Yeah, I mean, just kind of a quick trivial example.We clear the input and then we emit the event, which resets the coupon code. Yeah, I mean, just kind of a quick trivial example. And of course, you can make this as dynamic as you want. And then for your data, return invalids is all-free, something else. Yeah, and again, that could be part of an AJAX request. Quick and dirty. So we get a shot, all-free, that doesn't work. Something else, that doesn't work as well. But yeah, you know what, in real life, what you'd probably do is listen for the change event and then at that point, you'd maybe perform an AJAX call to ensure that the coupon Key Takeaways and Best Practices 7:56But yeah, you know what, in real life, what you'd probably do is listen for the change event and then at that point, you'd maybe perform an AJAX call to ensure that the coupon code is correct and get some data related to the discount percentage, things like that. That's probably a little more realistic. But yeah, that's beside the point. This is the key thing to understand. If you ever need to create custom input components, which you can think of as basic little wrappers around existing inputs where you add validation and sanitizing and behavior potentially, yeah, this is the way you would want to do it. You're going to use vModel to sync it with a root view instance.this is the way you would want to do it. You're going to use vModel to sync it with a root view instance. And then behind the scenes, you will bind to the value and then you will emit the input event. That's all there is to it.