This course has been updated! We now recommend you take the Introduction to Vue 3 course.

Check out a free preview of the full Introduction to Vue.js course:
The "Directives" 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:

Through some code demonstrations, Sarah reviews Vue.js directives. A directive is a special marker in markup attributes with the v- prefix that tells the framework to do something to a DOM element. Sarah takes questions from students.

Get Unlimited Access Now

Transcript from the "Directives" Lesson

>> Sarah Drasner: So directives are these tiny pieces of html attributes that view offers us. They're always prepended with this v and dash. And then it basically attaches some little piece of functionality to that bit of HTML mark up so that you're not diving into the DOM and doing something with it.

[00:00:20] You actually have all these things available to you. So there's tons of stuff here that we are going to work with today and look at but we are also gonna delve into custom directive. So if view doesn't have you covered for anything that you are using all the time, you can make your own.

[00:00:37] Which I think is really really great and very flexible. So that v-for that we saw earlier, we kinda went through li v-for, it loops through a set of values. That was the previous example, we said item in items. But we can also do a static number, it's very flexible.

[00:00:55] So we don't even actually have any data here to begin with. I'm just saying li v-for num in 5 and then outputting the number, and I can loop through it that way. Or if you need to, you have a set of data and you need to truncate it, you can do that with a number as well.

[00:01:15] So that's really simple and nice. V-model is one of my favorites, you've gotta have a favorite. [LAUGH] V-model is super awesome because it establishes a relationship between the data and like a form input. Which I feel for web developers this is the yak shaving part. This is the thing that we always have to kind of reimplement and reinvent the wheel, and view does this really elegantly.

[00:01:37] So you can dynamically update values. So if I have something like this data and then I have this message that this is a good place to type things, then I can output it I can output it here in this book text in that message but I establish a relationship between this text area that says, v-model message.

[00:01:59] And the rest of this is just HTML, this is like normal HTML. I have a text area, I gave it a class, I have some rows, I have a max length that's just normal html. So if we go look at this, I can go over to this over here and say hi front end masters.

[00:02:19] And, it's immediately outputting below. There's already that relationship, and it updates super automatically, so that's really really nice. It also means we can do more fun things with it, too. So, in this example, we're going to connect things like animation to it, which we'll do later on in the thing.

[00:02:36] I can still do, you know, write something like, hi, front and masters, and erase my previous one and print that one to the page and these will animate in the same fashion. So already you know half of how that is made. And we're gonna go into how the animation was done later but you can make really really beautiful interactions very very quickly.

[00:03:01] [LAUGH] Yeah.
>> Speaker 2: I have a question.
>> Sarah Drasner: Yeah.
>> Speaker 2: On that example the data property was a function?
>> Sarah Drasner: Yes, actually I am gonna dive into that a little bit later on. You can use an object for the data. So that's like the more simple way of doing it on the Vue instance.

[00:03:21] Although, I would really suggest that you always write data as a function and return it. Because what's gonna end up happening, and we're gonna go into much more detail about this when we get into components, is when we start breaking them into components we need to have each component have it's own isolated scope.

[00:03:36] And we can't do that unless it's a function. And we'll discuss that in more, that's a great question. Good eye for spotting that as well. So you're probably gonna see from here on, that most of the data that I'm using is gonna be returned as a function. In the beginning examples, I didn't use it that way so that it is as clean and small amount of code as possible.

[00:03:57] But that is how we're gonna end up using it most of the time.
>> Sarah Drasner: So, if we have, we can also use V-Model for things like check boxes and erase. So if I have something like John, Paul, George, and Ringo. I have all of these check boxes and this is again normal HTML input type and ID.

[00:04:17] And the label, the ID and for create a relationship for that. For screen readers between the label and the input, but I'm writing v-model checkNames. checkNames, if we go into the Vue app itself, we have established that relationship with the app and we say data checkNames is that array.

[00:04:38] So we go back over here and each one of these says v-model checkedNames, v-model checkedNames, v-model checkedNames and then we're just outputting checkedNames bellow, so that you can see it update. So that establishes a relationship with many things, instead of just one thing. But that's kind of repetitive, right?

[00:04:57] We said that we have that before there, so maybe we wanna dynamically show a bunch of options instead of sometimes you don't have control over everything that's gonna be in your checklists and you're actually creating these forms from something that a PM gave you or something. So we've got our options.

[00:05:16] We still got our checkedNames and an array that's empty here. And then we've got options with these values. When we go back to the input here, we're saying span v-for option in options. And then we're outputting option.value for the value. We're gonna cover this colon in in just a minute.

[00:05:37] But you can see that I can now establish a relationship with checkedNames and I don't have to keep typing that over and over again I can expand that list and contract it and I don't have to hard code and copy-paste. So that's pretty cool too. There are modifiers available to us.

[00:05:53] There's a lot of things again that we do with these kinda user input values, one of them is trim. We strip any leading or trailing white space from the bound string that's a really common use case. So it offers that right out of the gate. V- model.number changes strings to number inputs.

[00:06:10] If you're working with credit cards or payments, this is really awesome because you don't have to worry that somebody is gonna [LAUGH] just write their name or something, some kind of other user data there. We have v- model.lazy which won't calculate the content automatically. You saw that we were auto updating and running those updates every single time I typed.

[00:06:28] Well, there are instances where you don't necessarily need to do that. You're not needing to store every single keystroke. You can save v-model.lazy and capture it on an event instead. So when somebody submits a form that's when you get the user data, not from every single key press.

[00:06:45] So, that's actually how this is done. I wrote v-model.lazy and I'm storing the data until I actually hit that button, because, I don't actually need it until that time. So, it kind of helps me with performance. All right, we talked about v-model, we talked about v-form.

[00:07:01] Let's talk about some real true conditional rendering. We've got v-if and v-show, it's pretty straight forward, it's a conditional that would display information based on the requirements. But it's not just for HTML elements, you can show templates, you can show components, you can show large pieces of data, you can show small pieces of data.

[00:07:22] It's really super powerful. So if we go into this demo here, I can say Al Pastor, and you can see that that button shows up as I'm typing. I'm actually gonna open this one in another window. So we're gonna close this CSS pane. And we've got tacos is an empty string, it starts off as an empty string.

[00:07:46] So my v-if, my conditional here, is just waiting for some tacos to be there. Right now, it's an empty string, so v-if will not apply, so I can say, al pastor again That is my favorite taco and that button will appear or not appear. Let's go look at the DOM for just a second and by that I mean like the actual DOM.

[00:08:07] When we use VF. If we look inside of our elements here, we have this like empty comment that's just sitting there. And as soon as we start typing, Carne asada. You can see that that button shows up. And if I delete this it turns back into that comment right?

[00:08:30] So vf will literally unmount and remount that element into the dom. It will not exist during that time. So what is v show? These show if we change this V if tacos to V show tacos. It has the same functionality. I can say like hi and that button will show up or disappear.

[00:08:50] So let's go look at the dom again. So we've got this high and if we look at the button and then I delete this, you can see that that display none comes up. So the difference between V if and V show is that V if is completely unmounting and remounting that element.

[00:09:08] V show is just toggling its visibility for us. So, there are different use cases for both, right? If you have user content where you know the users gonna be clicking that thing, and making it appear or disappear a lot, then you probably wanna use vshow. Because you want that thing in the DOM, and that will be more performant because it's not gonna have to do so much work to have that show up.

[00:09:29] But if you have something like a full template or a full component or something that you're only showing in specific circumstances, your low time is gonna be much more or initially if you don't have to load out that content and then display none. So that's a good time to use [V if.

>> Sarah Drasner: V-if and v-else, we can't have v-if without v-else, right? We also have v-else if [LAUGH]. It's this one's pretty straight forward. You conditionally render one thing or another thing based on a condition. So in this case I have a couple of v-ifs, I have one v-if for tacos.

[00:10:04] And I say do you like tacos? Yes, is thumbs up and no is, you're a monster. And so you can see how we're rendering all of this if we go over, if we actually look a little bit closer. You know already that tacos is probably an empty string, right?

[00:10:23] Let's go check that out. It is definitely an empty string. And that whole thing is not gonna show up initially because I'm saying pv if tacos equals yes. And note the string that I'm using here if tacos equals yes. Then I get thumbs up. But, else is going to be the other condition.

[00:10:44] So, I don't want this showing up initially, because I don't want to just show the no originally. So, now I'm able to toggle those conditions, and you could see one or the other.
>> Sarah Drasner: V bind, this is another favorite. I have two favorites. Actually I have three favorites.

[00:11:04] [LAUGH]. V bind is super super powerful, and it's going to be even more powerful when we start working with props later. V-bind is written like this, but that's long to type for something that we're going to use so often. So there's a shortcut, and that's the colon. I'm mostly going to use the shortcuts from here on in, because I think that they're a lot cleaner.

[00:11:24] You can write it either way. That's up to you. It's one of the most useful directives so there's a shortcut. There's so many things we can use it for, we can use it for class and style binding, creating dynamic props, any kind of thing like this. So if we have something like, here's that button again, but this time the button is in the DOM.

[00:11:44] And if I write, thingy. You can see it show up or not show up but in active state or kind of a disabled state. So here we're v binding. So v bind or that colon class, yep?
>> Speaker 2: Could you just type the what it looks like with the v bind part?

>> Sarah Drasner: Sure.
>> Speaker 2: As suppose to the shortcut.
>> Sarah Drasner: I'm sorry. In the-
>> Speaker 2: In the HTML.
>> Sarah Drasner: Whoa, whoa, whoa. Sorry, let me open it in the other window. So it would be v bind and then I'll save it. So that it and then it goes like that.

[00:12:30] So basically that colon is still there. But the shortcut is just eliminating the V bind. Actually we'll just stay in this window cuz that's a nice. Get rid of the CSS. We have tacos, which is an empty string. You're used to that, tacos are empty strings today I guess.

[00:12:49] And we have this activeClass is active, that's why I had the CSS window open, right. So that you can actually see that button .active has a background of orange red so that's the thing that we're toggling. You can toggle any kind of styling that you need here. You can see that I'm just using a ternary expression in here.

[00:13:11] Ternary operators are really useful in directives. You can't write longer functions in directives. We'll use methods for that but if it's something simple then you can use ternaries.
>> Sarah Drasner: All right, so we can also do interactive style binding. So if we wanna make perspective work, and have some weird Tron thing, cuz I know this is a totally typical use case, we can do something like this.

[00:13:39] You might have seen demos like this done with CSS variables and connecting them to JavaScript, but this is super easily done in Vue. I'm binding to the style and changing the perspective origin based on e client x for the mouse. We're going to dig into methods a little bit more later, so don't really worry if it's befuddling now.

[00:14:02] Yes?
>> Speaker 2: Well Jennifer's asking a question on the v-if portion, why did you have it twice?
>> Sarah Drasner: Why did I have the v-if?
>> Speaker 2: The v-if twice in your previous-
>> Sarah Drasner: Yeah, I mentioned that actually. So if we go back to v-if, it's because initially, this v-else would show up, right?

[00:14:22] Like there are a couple of different ways I could have written this. I could have used an LSF as well. But initially, this v if tacos is yes. Having nothing there is not yes, so that v else would have, you know, shown up as, you know, another thing so I don't want no, I'm a monster.

[00:14:41] I actually don't want any of this. Showing up, I might put more data in there.I just don't want any of it to occur until I'm ready for it. That's a stylistic decision I could have written it another way and it would have worked as well.
>> Speaker 2: If you delete the first v if toggles, it should still run the same way, right?

>> Sarah Drasner: No, if I delete the first v if toggles-
>> Speaker 2: You leave the div part there. You just remove the V if toggles from it and it'd just explain empty div correct?
>> Sarah Drasner: It will show.
>> Sarah Drasner: No, you're a monster. I have to run it so because I'm not using that V if statement to hide all of this information, basically.

[00:15:26] I could have written it like V else if, as well but that's up to you.
>> Sarah Drasner: Cool. So, we've looked at now how we combined a style, so we don't even necessarily need to go into css and make a class for this. We can actually have things be super interactive right away just by binding a style in this pen.

[00:15:50] V-ONCE and V-PRE, these are not quite as useful. V-ONCE will not update once it's rendered. So it'll only update on that first time you entered it into the DOM, and then on user input, it will not change. V-PRE is a little bit more useful. It will print out the inner text exactly how it is so it's good for if you need to document your Vue components.

[00:16:14] It will actually show the mustache templates in every piece that you need in order to work with it. So I'll actually go through this and then we'll make it a little bit more clear. What is your favorite kind of taco? I like Al Pastor tacos, so here we've got, what is your favorite kind of taco?

[00:16:30] Actually, I'll go into the instance so that you can see what I'm working with. In tacos, I initially have, I like Al Pastor tacos. In the HTML, I have this v input v model for, we're establishing a relationship with that, tacos. And then when I type and then I have v wants beneath it, v wants tacos and then I am outputting tacos.

[00:16:54] And then if I type in here, you can see that I like Al Pastor tacos is not updating. So I could write I like carne asada instead. And that will actually update that view instance but it won't update this view once. I'm outputting the state down here. I'm outputting this data.

[00:17:17] Basically, whatever the view instance is using this is kinda like a little trick. I'm rating pre-tags here and then I'm outputting the data. And any time you see this $, you know it's something that's available that's special from the view instance. So this is kind of great for debugging.

[00:17:35] If you don't want to keep going back and forth to dev tools or debug Windows or anything, you can output what is going on in your data directly. Yep?
>> Speaker 2: Is this like the trick that they do with JSON stringify thingy?
>> Sarah Drasner: Yes, it's exactly the same thing.

[00:17:50] So if you've worked with React before, there's a similar way of debugging in React as well. And part of the reason I do it on this pen too, aside from you needing to see the differences here, is that, I can't type, is that, we have this v-pre. V-pre is not the same as that pre tag.

[00:18:14] That pre tag is pretty printing this code, it's not going to rate those handle bars data. It's actually going to process that information. This v-pre is not going to process this information. We have mustache view of tacos. So that is literally what is exactly on the page. If I wrote data like I have below, then you would see data.

[00:18:40] You wouldn't see it outputting. So even though we have v-pre, it's not exactly the same as a pre tag.
>> Sarah Drasner: All right V-ON or @, another favorite. [LAUGH] It's extremely useful. So there's a shortcut. V-on is great for binding to events, like click, mouse enter, mouse over. I had to learn the differences between those again the other day, cuz I had to look it up for the hundredth time.

[00:19:11] So you have all of these things available to you, kind of like normal JavaScripty things, and you attack that to a DOM element by writing that @ sign. You're able to pass in a parameter for the event like e or event, but you don't have to do that.

[00:19:28] You will automatically assume that you're gonna wanna capture that event and it will make that available to you in a method if you need it. We can also use ternary directly. So if we have something like this back pack, I'm gonna actually open this in another window. So let's say we have a store with this backpack and when you're working with the store, you probably want to add things but you don't want them to be able to remove things lower than zero.

[00:19:55] You want them to stop at zero. So in the data, we have this counter 0 that's really simple, and then we've got these button classes here. And, let's see if I can open this all the way up, it's a little bit easier to see. We've got these button classes that are the same.

[00:20:12] We have ternary expressions in these @click counters. So I can say counter and increment it by one, and that will increment it by one an then it will keep me from going anything below that on the other side. So we can also connect these to methods and we will do so in the next part of the course.

[00:20:33] But if you need it to just do, execute just a small amount of logic, you can do it directly inside of those, which is really nice. We can also do multiple bindings. There is a lot of times you need a hover on desktop, and on mobile you need something like a touch event.

[00:20:48] And so because you need those kind of things, you're able to actually use multiple things for that. So you can right click as on click and then we'd have a message for on click. Key up on key up and so on and so forth. This is how I would write that with the shortcut, just so that you can see the difference here.

[00:21:07] So v-on versus @. We have modifiers, yay modifiers. We don't have to keep reinventing the wheel. mousemove.stop is comparable to e.stopPropogation. mousemove.prevent is like e.preventDefault. If you wanna keep a form from re-submitting, you can do @submit.prevent and it will keep that form from reloading the page. @click.once is not the same thing as v-once, but kind of similar concept.

[00:21:37] The click event can only be triggered once in that instance, so sometimes you wanna disable that click right after it fires. That's how you would do it. @click.native is so that you can listen to native events in the DOM. This is kind of edge case thing, there's not a lot of things that you need where you need to capture the real DOM and not work with the virtual DOM.

[00:21:59] But there are some instances where you might need that. So Vue's got your back there as well and you can capture native events. There are keycodes available to you, like .enter and .spacebar or whatever. That might not be one actually, something like that. There are keycodes available to you.

[00:22:17] But you can also configure your own. If you decided you wanted to make a game with Vue, you could make key bindings with the arrows and things like that. V-HTML, it's great for strings that have HTML elements that need to be rendered. And what I mean by that is if you have something in this data tab, we have tacos, and I actually have a link inside this string.

[00:22:43] I don't want the string to output that <a> tag and everything that's inside that <a> tag, I want to just output it with the string attached so that I can hit the Al Pastor, we can go make ourselves some Al Pastor tacos. So that will actually parse of the strong tags and things like that.

[00:23:03] You should be really wary when you use this, and don't use it for user-generated content, because it's a security issue. If I wanna hack you, right now I'm just using an alert. But I hacked you and I stole all your tacos. I could do that if I was a user and I wanted to do some sort of cross site scripting.

[00:23:23] So don't allow users to give you any information that you're then outputting with the HTML. V-Text is similar to using moustache templates. This is my least favorite of all the directives because it's pretty much just the same as the moustache template. V-text tacos, tacos in here, it's the same, it's the same.

[00:23:47] I like Carne Asada. And you can see both of them update, it works very, very similarly. It's recommended to use mustache templates instead. You'll find that in the docs and things like that. I made a couple of different resources for you, like this table that has all of these.

[00:24:10] If you want to check it out, I wrote a big Vue guide on css-tricks, and all of that table and information is there if you need to go to that link.