Planning Vue Modal Setup0:30
We're going to migrate the technique from this episode over to a Vue component. Now granted, once you do that, it's no longer CSS only. But nonetheless, the CSS implementation is perfectly valid and usable. Okay, let's get started. So here is our setup. You'll see I have a page where we pull in Tailwind, and we have a heading. And that'll give us this. Okay, let's begin. As I see it, we need some kind of link that will open a modal. Now the way this works is by leveraging the :target pseudoclass in your CSS.
As I see it, we need some kind of link that will open a modal. Now the way this works is by leveraging the :target pseudoclass in your CSS. So that means we have to begin by linking to the name of the modal we want to load, maybe something like CancelModal. Okay, next, let's create the world we want. So I will have a modal component that we need to create. And here we'll have a heading, something like Leaving So Soon, and then, you know, some kind of lorem ipsum text. The only remaining step is to associate a name with the modal. That way, when we link to it, we know which one to open.
The only remaining step is to associate a name with the modal. That way, when we link to it, we know which one to open. So we'll give this a name of CancelModal. And again, notice those two match up because they're connected. All right, so actually, let's bring this down here. I think we're all set to go, so let's view it in the browser. If I load the page and then open Chrome Development Tools, it'll let you know, hey, I have no idea what that modal component is. So we have our next step. So we will import it, and then finally register it.
Creating the Modal Component1:49
So we have our next step. So we will import it, and then finally register it. And then, in fact, at the end of the lesson, I'll show you how to refactor this to a dedicated view plugin that you could even distribute if you wanted to. Okay, so now if I come back to Chrome and give it a refresh, let's see, something else. Cannot find the module modal. Well, yeah, of course. We haven't created it yet. resources/js/components/modal.vue. Here we'll have something.
Resources, JS, Components, modal.view. Here we'll have something. We'll have our script. And then finally, I know we're going to have a little bit of CSS. Okay, so now with that imported, if I give it a refresh, it should be cleared. Great. So I do see the contents of the modal right there. Okay, so the next step is to migrate the boilerplate from that other lesson we talked about at the beginning of the video. All right, now I don't want this to be confusing, so pay attention here.
Migrating CSS and Markup2:44
beginning of the video. All right, now I don't want this to be confusing, so pay attention here. This is our Playground workspace. I'm going to switch over to that modal example that we looked at earlier, and I'm going to switch to the main file. Okay, so here is the CSS for the modal. Again, I don't want to reinvent the wheel. I'm going to grab all of that and then switch back to our Playground and paste it in. Now we'll go over this in just a minute, but just come along for the ride. Next if I scroll down here, in that lesson, we used a Blade component for the modal.
Now we'll go over this in just a minute, but just come along for the ride. Next if I scroll down here, in that lesson, we used a Blade component for the modal. So I can go to modal.blade.php, and here is the wrapper for our modal. Pretty simple for the example. Okay, so once again, I'll switch back to the Playground, and if I scroll up, I'm going to paste all of that in here. Okay, so next, obviously we're not using php, so this will be our default slot. And then finally, the name of the modal. Of course, we're just going to use basic view data binding, and that means we need to accept it as a prop.
Of course, we're just going to use basic view data binding, and that means we need to accept it as a prop. Okay, so are we clear here? Take another look. We reference our modal component, and we give it the name, the identifier for the modal. Now that name is just being set as the ID of the overlay wrapper. So if I now switch back to Chrome, and we give this a refresh, and I click on this link here, instantly it works. I mean, how cool is that? And even the clicking away, with typical JavaScript, that can sometimes be a little awkward, in
Explaining CSS :target Behavior5:38
Now if you're not familiar with this, target allows us to effectively say, if this element matches what you have in the URI as the hash, then it is the target. In fact, let me just show you. Here it did with an id of app. Let's create a new one here. If app is the target, then set a background color of green. Okay, I don't see anything because app is not the target. Let's make it the target, and now it is green. So once you understand that, it then becomes almost laughably simple. We just have to say overlay if it's the target.
So once you understand that, it then becomes almost laughably simple. We just have to say overlay if it's the target. So now notice, if I click on this, actually cancelModal is the target, not overlay. So what's going on there? Well note, if we scroll up, the class, yes, is overlay, but that's associated with the ID of cancelModal. So both will work in that case. All right, so all we have to do is say, well, if you click on a link that sends the user to that anchor #, then update the visibility to visible, and that's it. The rest of this is basic CSS to style the window.
Adding Named Footer Slot8:51
Okay, so anyways, we have our cancel link, and then maybe you have, I don't know, a link to continue to another page, whatever is appropriate. Maybe it's a button, anything you want. So if I refresh, though, I'm not going to see it, and that's because we've set up a slot section for the footer, but we aren't referencing it anywhere within our main component. Why don't we do it, how about, right down here. And here I can have my slot, which we called footer. Okay, so now they will show up. So a quick little heads up here, depending on when you're watching this, this is actually a new thing as of Vue 2.6.
So a quick little heads up here, depending on when you're watching this, this is actually a new thing as of Vue 2.6. So if you're working along and you can't get it to work, check your Vue install or your package.json, and make sure you have at least 2.6.10. And that's because as part of that release, name slots and scope slots, the syntax was normalized to make things a bit simpler. So now you'll want to use a <template> tag, and then you specify the name, in this case it's footer. And in fact, if you want to accept some slot props, you could do it here. Like if you wanted to accept foo, and then you could pass it in here.
Anyways, that's something to think about. But we'll skip that step for now. Now another cool thing with this approach is it becomes super simple to load different modals. So for example, here we have a cancelLeak. Maybe we'll have another one for pleaseConfirm or confirmCancellation. And that loads one more modal. Or maybe it links to join, whatever. Let's create one more. And we'll say confirmCancelModal.
Refactoring into Vue Plugin13:59
Again, it's a super clever technique. I wish I had thought of it. I can't take credit for it, but I can use it. So finally, this is all working, but if you'd like some extra credit as a bonus, let's learn how to refactor all of this to a Vue plugin. In my resources directory, I'm going to create a new plugins folder, and this will be for our modal. Okay, so we need two things within here. The plugin itself, I'll call it modal-plugin. And then one more, plugins, modal-directory, and this will be for the component.
The plugin itself, I'll call it modal-plugin. And then one more, plugins, modal-directory, and this will be for the component. We can just call it component. Okay, so I'm going to take our entire component here and move it into our new plugin, and then I'll delete that. Next, let's close this out, and in our app.js directory, we're no longer going to import and register the modal. Instead, we're going to pull in a plugin that will do all of that boilerplate work for us automatically. We can do it like this, import modal from, go into your plugins directory, modal, and
Vue and any options that the user passes. Okay, so I can say, hello there, and we can give this a shot, a real quick, quick overview. So in our setup, we import Vue, we import our modal. Our modal exports this object that only includes an install method, and that method alerts to the user. Next, we tell Vue to use our plugin. So let's give this a shot. If I give it a reload, hello there. Okay, so now here, we can do anything we want. We can register mixins, we can register components, we can add to Vue's prototype, we can set
Okay, so now here, we can do anything we want. We can register mixins, we can register components, we can add to Vue's prototype, we can set default options, anything you want. So that means if I were to switch back, you will see in the console, we're back to this issue because we haven't registered the modal component. All right, let's do that. Vue.component, modal. If you were distributing this to others, that should be configurable because maybe it interferes with something else they have. So maybe you would have something like options.name while setting a default.
So what do we do? We still want to use this functionality, but I want this to be a button. Well, we should offer some way to programmatically change it. So what you could say is, well, if you click on this button, maybe modal.hide cancelModal. We should allow programmatic access, even if behind the scenes it's still doing that same thing where it updates the hash. At least we have a programmatic way to do that. Okay, let's give this a shot. We know it's not going to work, but if I give it a refresh, I click on it, nope, there is no method modal on our instance.
We know it's not going to work, but if I give it a refresh, I click on it, nope, there is no method modal on our instance. Okay, that sounds like a use case for our plugin. So right here, we could say, let's just add to the view prototype. And let's see, how did we reference that? We're adding this modal object to the prototype. So it should have a show and a hide method. And what's nice is, you now have a single place to decide how that works. Are we updating the hash? Are you firing an event?
Are we updating the hash? Are you firing an event? Are you updating some kind of store? Whatever you need to do there. In this case, we're updating the hash. So I could say location.hash equals the name. So again, if I say modal.hide, you send through the name of the modal. So to show it, we set the hash equal to that name. To hide it, we do anything else. So we're going to accept a name, but we don't even need to use it for this implementation.
To hide it, we do anything else. So we're going to accept a name, but we don't even need to use it for this implementation. And we get something like that. Okay, so now our plugin has registered a global view component, and it's also added to the view prototype, which means any view instance you have will have access to this modal now. Okay, so let's see if this works for us. We give it a refresh, no issues, we click cancel, and now that's working as well. So you can either use an anchor tag to toggle the display, or you can programmatically do it. So just to show you in our view instance, here is our modal.
it. So just to show you in our view instance, here is our modal. I'm going to access it with that vm0 temporary variable name, and you'll notice I now have access to that modal object. So I can hide it. And now it's gone. So if I switch back, I'll let you take a final look at our very, very simple implementation. There's the plugin. Here is the modal component itself. Here is our main app.js file, where we import the plugin, and then we tell view to use it.
Here is the modal component itself. Here is our main app.js file, where we import the plugin, and then we tell Vue to use it. And then finally, here is where we would actually use the modal. So you'd have some link that will direct the user to a hash, and then you need to have a modal that corresponds to that hash, like we've done here.
