- Read Tutorial
- Watch Guide Video
Let's look at the application first is I'm going to leave this in the show notes so don't worry if you want to reference it you can reference the app.js
in the show notes and you can see how we're going to toggle the image. But what I want to build out now is actually a image Options button.
So instead of just showing or hiding something what I want to do is to be able to click on this and have the image go to multiple sizes. So it's going to start off small, kind of a thumbnail size then if I click the button again I want it to expand out to be more medium size, if I click it again I want it to go large and then if I click the button one more time I want to go small again and it can just cycle through those options.
Now, this guide is going to be a little bit longer than the other ones because I'm going to show you two ways to do this. I'm going to show you a way where you integrate your conditional directly into the component. So if we take a look at this you have the ability inside each one of these functions to add any kind of JavaScript code that you want. So in here you can add conditionals you can have your compound conditionals you can change the data values implement your own behavior or anything like that that you need to do.
The only thing you really shouldn't do here is directly manipulate the DOM, so you shouldn't add your own selectors or anything as if you were working with vanilla javascript. You should simply deal with the data that you have direct access to the inside of the component. So I'm going to show you how you can implement a conditional here and change those values dynamically.
After that we're going to create a second implementation and I'm going to show how you have a compound conditional directive so we don't just have a v-if
we also have the ability to say v-else-if
and to be able to add other conditions which can be very helpful. I'm not going to say that one of these options is really better than the other one.
I think in many cases especially if you're using some type of other frameworks such as Rails or Laravel or something like that then it can be very common to need to implement this type of conditional logic directly in the HTML file. Then also if you have anything that is purely data related then I think it makes logical sense to put that inside of the component itself.
So with all that being said let's start actually building this out. So in our index.html
I'm going to keep some of this code but we're going to change it up a little bit. Instead of saying imgToggleClick
, I want to name this function showImgOptions
and then here let's change the button so it's really clear what we're looking to doShow Options
is perfectly fine.
Now inside of our image, we're not going to have a conditional but instead inside of this image we're going to have the same call to the URL. And now I'm going to change the width, so I'm going to keep this image width and I'm going to make it dynamic, but no longer are we simply going to rely on a hardcoded value, we're going to make that part dynamic and then I'm also going to show you how we can do the same thing with the height,
Because we have a colon in front of the width and height, it means that we now are telling Vue that this is an attribute directive. We have the ability to type in any values we want here.
So right now if I switch back we're going to get some errors because we have not implemented a number of these things, we haven't built out that method. We don't have a height attribute and it's still showing the image but we need to fix those things first.
So coming back up to our app.js
component, right underneath our image width let's also build out an image height so it's going to be image height. Just like that. And now we have access to it now. The other thing I'm going to do is I'm going to build out a few other boolean values.
app.js
new Vue({ el: "#app", data: { name: "Kristine", imgWidth: 150, imgHeight: 150, showImg: true, smallImg: true, medImg: false, lgImg: false }, });
I'm going to get rid of the imgToggleClick
. Do not worry it is in the show notes so you can reference all of this. Just like everything else in all the courses they do you have access to all of the source code. Now the method that I have here is called showImgOptions
let me select all of this and let's actually call this function.
app.js
}, methods: { greeting(nameFromView) { return `Hi, ${nameFromView}`; }, showImgOptions() { } } });
Now this is going to be a very long method, it's much longer than most the methods I usually like to use but I think that it's a good exercise to show you how this works and also you're going to be able to see side by side how it works when you want to implement compound conditionals directly in the javascript component versus putting them in the template with directives.
app.js
}, methods: { greeting(nameFromView) { return `Hi, ${nameFromView}`; }, showImgOptions() { if (this.smallImg) { this.imgHeight = 250; this.imgWidth = 250; this.smallImg = false; this.medImg = true; } else if (this.medImg) { this.imgHeight = 350; this.imgWidth = 350; this.medImg = false; this.lgImg = true; } else { this.imgHeight = 150; this.imgWidth = 150; this.lgImg = false; this.smallImg = true; } } } });
Okay, that was a decent amount of code. And typically I don't like my conditionals to be quite this large. But for the sake of being able to see how this works, I think it's fine. So let's come back it looks like so save it and now let's see what we have.
So if I click on show options you can see this is working beautifully. So you click here instead of it showing and hiding what it's doing now is it's changing. Each one of those values inside of the conditional. So that is exactly what we want it to do. So you have a button here that has a click listener, and then it calls the show image options function and then it's altering this value.
Now let's now see the other way of doing this. I'm going to copy all of this and actually let me wrap this all in a div as well just to make sure make it kind of a little bit easier for us to see how it's working in comparison with the next one we're going to do it all in a div. And now let's just copy all this code because it's going to be kind of similar.
Now what we're going to do is we're going to build another function I'm going to call it just altShowImgOptions
just so we can see it side by side. So we're not going to override this value.
So say OLX show image options just so we know exactly what button we are pressing case an alt show options. Everything here is going to be the same. To start off with but instead of us calling an outside function and having the conditional logic or all the conditional logic inside of here what we're going to do is we're now going to add some conditionals.
So let's come here. And so inside of this image, I'm going to say v-if="smallImg"
equals and then say small image and then right here instead of using a directive. Now I'm just going to hard code these values end so now just say 150 for the width and then one 50 for the height. And now I can change this conditional.
index.html
<div> <div> <button @click="allShowImgOptions">Alt Show Options</button> </div> <img v-if="smallImg" src="images/logo-with-margin.png" width="150" height="150"> <img v-else-if="medImg" src="images/logo-with-margin.png" width="250" height="250"> <img v-if="lgImg" src="images/logo-with-margin.png" width="350" height="350"> </div>
So that is all we need on that side. But now we actually have to build out this function. So we are not completely done yet. So let's come to app.js
and copy that code or that method name I should say.
app.js
}, methods: { greeting(nameFromView) { return `Hi, ${nameFromView}`; }, showImgOptions() { if (this.smallImg) { this.imgHeight = 250; this.imgWidth = 250; this.smallImg = false; this.medImg = true; } else if (this.medImg) { this.imgHeight = 350; this.imgWidth = 350; this.medImg = false; this.lgImg = true; } else { this.imgHeight = 150; this.imgWidth = 150; this.lgImg = false; this.smallImg = true; } } altShowImgOptions() { if (this.smallImg) { this.smallImg = false; this.medImg = true; } else if (this.medImg) { this.medImg = false; this.lgImg = true; } else { this.lgImg = false; this.smallImg = true; } } } });
You can see it's still working perfectly. Now if I click on this one it's also going to be changing this value. Just like that. But that's only because I kept the same names for those bullion value so it's actually changing those dynamically. Here it's not because here all we're doing is we're altering the DOM with our directives. So right here just in review to see exactly what's going on.
We have show image options here. This is where we placed all of the logic for both the data layer as well as the boolean value so for the size of the image along with changing the state we are doing that here. Now in this spot, we're only changing those boolean values to say which one should be shown and which one shouldn't be.
Now the difference as you can see is pretty significant because here we have our conditional logic directly in the view where we have these set of if else statements were up here. We just have a single image that allows us to dynamically change the width and the height attributes. Now there is there is really not a right or wrong way to do this.
The reason why this guide is a little bit longer than the others is that I wanted to show you both of the options. One thing I really like about Vue is it lets you build your system however you want. One of the other things I don't like about Vue is it lets you build your system exactly the way you want. And so because of that, there's a lot of flexibility and so right here you can see that you can see that we've built identical behavior and we use two very different types of implementation in order to do that.
Now if you want kind of a rule of thumb or what I personally use as my rule of thumb is usually try to place as much of the conditional logic as possible inside of my component file mainly because I try to keep out a lot of logic from the DML site but there are times where this conditional directive can be very helpful.
The most common time is when you're dealing with users that are logged in or that maybe don't have all of the permissions as other users. So a great example would be that you have a site and you want to have a different set of navigation buttons. So if users logged in then you want to show them a profile link. But if they're not logged in you want to show a sign in and a register link.
Well, that is a perfect use case for using this type of directive because it gives you a really clear way of defining exactly what should be shown on the page. And you also have a limited amount of duplicate code whereas in other circumstances where you want to be able to dynamically change values of a single element then that could be a great use case for using a different type of conditional like we used up here in this first example.
So hopefully being able to see those two side-by-side first, seeing that both of them are possible so you can have your conditional logic directly in the view or you can have it in your component. First and foremost it's important to understand that both of those options are possible. But secondly, I hope that you will now start to think through when you want to use one implementation versus the other.