This course has been updated! We now recommend you take the Introduction to Vue 3 course.
Transcript from the "Custom Directives" Lesson
[00:00:00]
>> Sarah Drasner: Custom Directives. We're almost done with this section. Custom directives are super awesome. We covered directives in that first one and we saw how powerful they can be. We're just attaching a small bit of markup to that attribute, and then we're able to have low level access to that VDOM or DOM element.
[00:00:17] And that it allows us to do all sorts of things, like set up a relationship in v-model. Or say v-for say the be v-if, and do all sorts of calculations. And Vue's got you covered for a lot of the kind of typical UI building things that you might need to do.
[00:00:36] But every once in a while, you'll find that you have a certain type of application where you need something. Again and again, that would be really useful as a directive, but Vue doesn't offer it because it's something specific. So custom directives can be really powerful for this. So if we do something like say, v-tack.
[00:00:55] I'm gonna create something called v-tack, then I can create view.directive'tack'. I am doing this again, and I'm in that main.js file above the Vue instance. I am saying bind(el, binding vnode) and I'm just passing an element and saying el.style.position fixed, so that's okay, that's not that great. We're gonna do more with it in just a second as I cover directives.
[00:01:22] So we went over directives really quickly in the beginning but we didn't do a deep dive to what is actually going on with each one of them. V-example, this will instantiate a directive but doesn't accept any argument, so this has limited use. This is what we just saw on the other one, we were like, okay we made it position fix.
[00:01:42] Cool, but we're not passing any values or anything, so there's very little we're actually doing with it. Better, as we could, and this is what we've been using a lot today, was things like v model = message or something. V-example = value. This will pass a value into the directive, and the directive figures out what to do with that value.
[00:02:04] So we have div v-if = stateExample, I will show up if the stateExample is true. Then we can say v-example = string, this will let you use a string as an expression. So you can do something like those strong tags, we saw that earlier with the HTML. We can also do something have an argument.
[00:02:28] So if we have an argument to the directive, remember we were using things those class and style bindings, that's an example of an argument. We did v-bind: and then style or class and we could get lower level access and also pass an argument. If we have v-example:arg.modifier="value", this allows us to use a modifier.
[00:02:53] The example below allows us to call preventDefault() on that thing, so you used this earlier as well. So, these are all the different ways you could create a custom directive. So here we've got, it's a little bit late on this screen. But if you go into the slides, you can see this a little bit better.
[00:03:14] There's actually things surrounding this. So we've got a few different hooks that are available to use with custom directives that are different from our life cycle hooks. We've got Bind, that's the insertion into the DOM, inserted is the element is inserted, updated is the element is updated. And in the cases that it's updated, we have access to the v-node and the old v-node.
[00:03:39] Remember when we were working with watchers and we had access to the old value and the new value? Very similar concepts. We also have component updated, where all the children are updated, and they have v-node and or old v-node and we also have unbind. Most of the time, I use bind, so that will probably usually get you where you need to go, but there are specific instances where you might want these other ones.
[00:04:06] So if we look again at this example, we've got that v-tack, we're making that position fix, that doesn't do much. Now let's make it a little bit better. So v-tack 70, I've got a value that I'm passing in. And then I've got this Vue.directive, we got bind and we're passing in the el.style.position is fixed and then we're saying top binding value plus px.
[00:04:33] And now we can scroll down the page and stick an element from the top of the page. Wherever we need to just by saying v-tack, I'm going to immediately be able to tack things to the page at a certain distance from the top. So maybe we need to pass an argument, maybe we want to sometimes make it stick to the left of the page instead of the top.
[00:04:57] So I could say something, usually we want the top, but in certain circumstances where we pass this argument, make it left instead. So that makes me happier and we can do, I'll be offset from the left instead of the top and you can see me scrolling, and it allow me to scroll and it's stuck to the page.
[00:05:19] We can pass more than one value, we looked at this earlier again when we looked at those at events and things like that when we were trying to bind to touch, as well as hover and things. We can say top 40 left 100, and say something the position is fixed.
[00:05:35] The binding that value.top plus px, and the binding that value.left. So I'm tacking it from 40 from the top and 100 px from left of the page. So that's pretty cool. Now we have a little bit more functionality in there. So let's make something that we might use, that's kind of a normal thing that we might make.
[00:05:59] I use a library called Waypoints pretty frequently and what Waypoints does is it allows you to attached a trigger or hook to some sort of scroll of them. You can basically say, when it gets to this point in the page, fire something and off of that, I might have an animation or I might have something toggle or some event occurs as your kind of scrolling.
[00:06:24] And Waypoints is beautiful and kind of slender, but it's still a library that has a few kilobytes worth of JavaScript in it. With Vue and custom directives, I can mimic all functionality of that really, really simply in just a few lines of code. So this custom directive with the scroll event, I'm basically saying okay, add this event listener and listen for this point of pixels down the page and then remove that event listener when I'm done with it.
[00:06:56] So I'm just passing in a few different value in this like what, ten line of code, I can get ride of an entire library. So then I can pass in a method that attaches to that directive and has animation logic fire when I get to that certain point in the page.
[00:07:15] So if I have v-scroll and then I'm attaching to that method handle scroll, I can have that thing kind of show up on the page as I'm scrolling, so if I'm building that out even further. I'm working on a project where I'm working with D3 and hooking a bunch of D3's functionality into that directive.
[00:07:35] It's not open source yet because I have a lot more work to do. But this is basically how it's all working. So I'm able to all sorts of D3 events just by hooking them into that tiny little piece of directive that I can use and reuse.