Build an Alert Vue Component — Transcript

Transcript of the free Vue.js lesson Build an Alert Vue Componentwatch the video lesson.

Before we end the course, I'd like you to try your hand at one more component coding challenge. In this one, you're going to build an app alert component. You've probably seen alerts much like these in apps you use every day. Alerts that give you some kind of information, alerts that tell you you have completed some action successfully, alerts that warn you that something is not valid, or alerts that tell you an error has occurred with the system.

Now I have grabbed these alert styles right here from daisy UI. So they have an alert component. Essentially it's an element with the class alert and then alert dash whatever type of alert it is. I've copied the markup from the website and I've used it to power the component.

You are welcome to do the same. or create your own styles completely without daisy UI. It's totally up to you. The point is, is that you create a component that acts like an alert.

It should take in a type prompt. This will determine the color of the alert. And optionally, you could also customize the icon for the alert as well, depending on the type. And then it should also include a X.

When the X is clipped, It should hide the alert, but I also want you to support a close custom event. Meaning, whenever the alert is closed, this event is fired, and I could handle it in the parent component however I'd like. In this case, I'm just console logging closed when the alert closes. Not super useful, but there can be good use cases for this.

Go ahead and practice creating this alert by yourself. You will absolutely have to use props, of course. You will also have to use component custom events. That is your challenge.

Good luck. Come back when you're ready to see the solution. Welcome back. Let's take a look at how to build this app alert component now.

I've created the component. It lives inside of the components directory and it is basically empty. Let's get things started. by copying the html here for the first alert type from daisyui.

Remember you could have created this from scratch yourself if you wanted to practice the styling or if you just don't like tail end or daisy. So now I have four info alerts over in the browser. view file. I'm not using any of the information that's being passed to them though as I'm not supporting a slant, so the message is not custom per alert, and I'm not supporting the prop yet, as the alert colors are all the same.

So let's start by supporting the prop. Inside of script setup, just like in our last challenge, I'll need to call the find props. The prop that we want to support is a type, and the type prop will be of the type string. Now, I think it makes sense in this instance to provide a default type.

What about info be the default, and we'll say the user has to specify any other type. Now, what do we do with this type? Well, remember, in daisy UI, we can simply append the type to alert- in the classes, and that will change out the colors for us. So let me do that over here.

Right here, we have hard-coded alert info. Let me make this dynamic Make this a string and then interpolate our type from the props Do notice that we can use type directly inside of the template. We don't have to set props first We can access type directly because the template automatically has access to those Now in the browser everything is the proper color There is one small caveat here though since we're using Tailwind CSS. If you aren't familiar with Tailwind or don't plan on using Tailwind, you can basically ignore what I'm about to tell you, but this is kind of a special thing that has to do with the way Tailwind creates your style sheets.

Tailwind actually crawls through all your code and checks to see if certain classes exists so that they will be included in the final style sheets when we deploy for production. Since we're working in development right now, literally every single style that ships with Tailwind CSS and daisy UI is being shipped to the browser. And so this dynamic alert dash class name here or type works. However, we need to actually have these full strings written somewhere inside of our code so that when Tailwind crawls our code, it finds these in full.

and the nose to include it in the final bundle, the final CSS output. In order to do this, it is a little bit more, doesn't look quite as nice, but this is what you'd have to do. I'll create a computer prop here called type, and we'll have to import computed from view, and then I'm essentially gonna create a map that maps all the types to the proper class needed to display that type. So that would be info, would map to alert info, warning, alert warning, and so on.

Then we can just use alert type down here instead of doing this kind of concatenation of them together. Whoops, everything went back to the default styles here. Our issue is that we aren't selecting which one. type, come up here.

capture the prompts as the return of defined prompts and now the first time for the first alert over here type will be info and so it'll find the info key inside of our object and it will return the class alert info the second time around here it will be I don't remember let's see it will be a success message and so it'll it'll be success right here which will find success inside of the object and therefore the class will be alert success So all of this works just fine, except we have mapped error to alert warning. We'll change that. Great. Okay, the next thing we want to do is change out the icon based on what type of alert we're dealing with.

js is to actually create a component dedicated to that icon. and then just providing the SVG for the component. vue file, and then just pasted the SVG in. I did the exact same thing for icon info, icon success, and icon warning.

Okay. So back inside of App Alert, let's just import each of those different icons. I will copy and paste it from another file here so we can do that quickly. And then let's create yet another computed map in order to choose the proper icon.

And I'll copy and paste this as well. So you can see we have a icon computed property. Once again, we're using the props type to pick the proper icon from this object. and each type is mapped to a specific icon.

Great. So now instead of providing the static SVG down here, what I will do is provide a special component. js and this allows us to dynamically display any component. I can say is and then pass it the icon that I want to display.

So that is the icon that comes out of this computed prop here. Over in the browser you can see now we have the proper icons for each alert super super cool Another way you could have done this is with conditionals So I could have said right down here icon success the if type equals Success and I could have done this for every single type right, but this just seemed a little bit shorter and sweeter Great, so we have all the alerts looking like we want them The last thing we need to do is provide the X in order to close them. Oh, and we still need to display the proper message as well. view, you can see I'm passing the message via a slot.

So that means I need to provide a default slot somewhere inside of my app alert component. And the place that I want the message to appear is right here inside of the spam. So let's add in the slot. And now the messages are correct.

Lastly, let's add in that X. So right down here, I will create a button because we want to be able to click on it to close it, right? So a button is the semantic thing we should use. And then I'll just look through my icons here and find a nice X.

You could type out an actual X. I found that this icon just looks a little bit nicer. You could have provided an SVG. That is totally up to you.

But now whenever I click on this, I want to hide the alert. So I'll say at click equals close. Then we'll define a function up here called close. And I'll create a piece of state called closed.

It'll be false by default, which of course means we also need to import ref from view. value equal to true. Lastly, I want to only display the alert if the alert is not closed. So over my browser now, I will click an X and indeed the alert disappears.

The last thing I want to do is emit an event whenever the alert closes. So the first thing you should do when emitting an event is define emits. view. That means this at close listener should now work as expected and we get a console log whenever we close the error task.

Let's give it a try. I have my console open on the left-hand side. Click it and it looks like we don't have a console log. That's because I called this close and the emit closed.

So let's just update this to have a D on the end. opening up my console one more time, refreshing the page, click close, and sure enough, there it is. Okay, that wasn't super helpful to have a listener in that case, but let me show you an example where it would be very handy. Let's say I haven't hard-coded each of my app alerts down inside the template.

Instead, I have an array of each of the alerts inside of Script Setup. So something like this. Here I have an array. Each object within this array describes a type of alert.

So we have a success type with the message of the same as the success in the template below. Then we have a error type with the same message as in the template below and so on and so forth. I think you get the idea. Now I need to import ref from view.

And then finally, instead of having each one hard-coded, we will say v4 alert and alerts. Provide a key for each one because Vue likes to have the key with your v4s. And the thing that is unique in each of these is probably going to be the message. And then inside of the slot, we will echo the dynamic message here.

Lastly, we will make the type dynamic as well. Cool, this works. Now we have a green alert with the proper message and a red alert with the proper message. Let's print out the alerts right here though, just down below so that we can see what that looks like.

So here is our array with two alerts in it. If I close one of our alerts now though, notice that it still exists inside of the array. This is actually a setup I've seen pretty often in real life apps. what I want to do is listen for the close of the alert and remove that alert from the array so that our data is consistent with what's being shown on the screen.

So I'll get rid of this handle close function that we weren't doing anything with, break this down to a new line so it's a little easier to read, and then we'll say at close we want to set alerts equal to alerts with the closed alert filtered out. So A is the current alert being iterated over. message. Great.

This essentially says return all the ones except the one that was just closed. Now over in the browser, when I close an alert, the error one does disappear and the success is the only one left. If I close the success alert, then it is removed from the array as well. I hope this lesson was helpful to show you yet another practical example of what a component might look like and gave you good hands-on practice defining an alert component using prompts, using emits, and using slots.

Before we end the course, I'd like you to try your hand at one more component coding challenge. In this one, you're going to build an app alert component. You've probably seen alerts much like these in apps you use every day. Alerts that give you some kind of information, alerts that tell you you have completed some action successfully, alerts that warn you that something is not valid, or alerts that tell you an error has occurred with the system.

Now I have grabbed these alert styles right here from daisy UI. So they have an alert component. Essentially it's an element with the class alert and then alert dash whatever type of alert it is. I've copied the markup from the website and I've used it to power the component.

You are welcome to do the same. or create your own styles completely without daisy UI. It's totally up to you. The point is, is that you create a component that acts like an alert.

It should take in a type prompt. This will determine the color of the alert. And optionally, you could also customize the icon for the alert as well, depending on the type. And then it should also include a X.

When the X is clipped, It should hide the alert, but I also want you to support a close custom event. Meaning, whenever the alert is closed, this event is fired, and I could handle it in the parent component however I'd like. In this case, I'm just console logging closed when the alert closes. Not super useful, but there can be good use cases for this.

Go ahead and practice creating this alert by yourself. You will absolutely have to use props, of course. You will also have to use component custom events. That is your challenge.

Good luck. Come back when you're ready to see the solution. Welcome back. Let's take a look at how to build this app alert component now.

I've created the component. It lives inside of the components directory and it is basically empty. Let's get things started. by copying the html here for the first alert type from daisyui.

Remember you could have created this from scratch yourself if you wanted to practice the styling or if you just don't like tail end or daisy. So now I have four info alerts over in the browser. view file. I'm not using any of the information that's being passed to them though as I'm not supporting a slant, so the message is not custom per alert, and I'm not supporting the prop yet, as the alert colors are all the same.

So let's start by supporting the prop. Inside of script setup, just like in our last challenge, I'll need to call the find props. The prop that we want to support is a type, and the type prop will be of the type string. Now, I think it makes sense in this instance to provide a default type.

What about info be the default, and we'll say the user has to specify any other type. Now, what do we do with this type? Well, remember, in daisy UI, we can simply append the type to alert- in the classes, and that will change out the colors for us. So let me do that over here.

Right here, we have hard-coded alert info. Let me make this dynamic Make this a string and then interpolate our type from the props Do notice that we can use type directly inside of the template. We don't have to set props first We can access type directly because the template automatically has access to those Now in the browser everything is the proper color There is one small caveat here though since we're using Tailwind CSS. If you aren't familiar with Tailwind or don't plan on using Tailwind, you can basically ignore what I'm about to tell you, but this is kind of a special thing that has to do with the way Tailwind creates your style sheets.

Tailwind actually crawls through all your code and checks to see if certain classes exists so that they will be included in the final style sheets when we deploy for production. Since we're working in development right now, literally every single style that ships with Tailwind CSS and daisy UI is being shipped to the browser. And so this dynamic alert dash class name here or type works. However, we need to actually have these full strings written somewhere inside of our code so that when Tailwind crawls our code, it finds these in full.

and the nose to include it in the final bundle, the final CSS output. In order to do this, it is a little bit more, doesn't look quite as nice, but this is what you'd have to do. I'll create a computer prop here called type, and we'll have to import computed from view, and then I'm essentially gonna create a map that maps all the types to the proper class needed to display that type. So that would be info, would map to alert info, warning, alert warning, and so on.

Then we can just use alert type down here instead of doing this kind of concatenation of them together. Whoops, everything went back to the default styles here. Our issue is that we aren't selecting which one. type, come up here.

capture the prompts as the return of defined prompts and now the first time for the first alert over here type will be info and so it'll find the info key inside of our object and it will return the class alert info the second time around here it will be I don't remember let's see it will be a success message and so it'll it'll be success right here which will find success inside of the object and therefore the class will be alert success So all of this works just fine, except we have mapped error to alert warning. We'll change that. Great. Okay, the next thing we want to do is change out the icon based on what type of alert we're dealing with.

js is to actually create a component dedicated to that icon. and then just providing the SVG for the component. vue file, and then just pasted the SVG in. I did the exact same thing for icon info, icon success, and icon warning.

Okay. So back inside of App Alert, let's just import each of those different icons. I will copy and paste it from another file here so we can do that quickly. And then let's create yet another computed map in order to choose the proper icon.

And I'll copy and paste this as well. So you can see we have a icon computed property. Once again, we're using the props type to pick the proper icon from this object. and each type is mapped to a specific icon.

Great. So now instead of providing the static SVG down here, what I will do is provide a special component. js and this allows us to dynamically display any component. I can say is and then pass it the icon that I want to display.

So that is the icon that comes out of this computed prop here. Over in the browser you can see now we have the proper icons for each alert super super cool Another way you could have done this is with conditionals So I could have said right down here icon success the if type equals Success and I could have done this for every single type right, but this just seemed a little bit shorter and sweeter Great, so we have all the alerts looking like we want them The last thing we need to do is provide the X in order to close them. Oh, and we still need to display the proper message as well. view, you can see I'm passing the message via a slot.

So that means I need to provide a default slot somewhere inside of my app alert component. And the place that I want the message to appear is right here inside of the spam. So let's add in the slot. And now the messages are correct.

Lastly, let's add in that X. So right down here, I will create a button because we want to be able to click on it to close it, right? So a button is the semantic thing we should use. And then I'll just look through my icons here and find a nice X.

You could type out an actual X. I found that this icon just looks a little bit nicer. You could have provided an SVG. That is totally up to you.

But now whenever I click on this, I want to hide the alert. So I'll say at click equals close. Then we'll define a function up here called close. And I'll create a piece of state called closed.

It'll be false by default, which of course means we also need to import ref from view. value equal to true. Lastly, I want to only display the alert if the alert is not closed. So over my browser now, I will click an X and indeed the alert disappears.

The last thing I want to do is emit an event whenever the alert closes. So the first thing you should do when emitting an event is define emits. view. That means this at close listener should now work as expected and we get a console log whenever we close the error task.

Let's give it a try. I have my console open on the left-hand side. Click it and it looks like we don't have a console log. That's because I called this close and the emit closed.

So let's just update this to have a D on the end. opening up my console one more time, refreshing the page, click close, and sure enough, there it is. Okay, that wasn't super helpful to have a listener in that case, but let me show you an example where it would be very handy. Let's say I haven't hard-coded each of my app alerts down inside the template.

Instead, I have an array of each of the alerts inside of Script Setup. So something like this. Here I have an array. Each object within this array describes a type of alert.

So we have a success type with the message of the same as the success in the template below. Then we have a error type with the same message as in the template below and so on and so forth. I think you get the idea. Now I need to import ref from view.

And then finally, instead of having each one hard-coded, we will say v4 alert and alerts. Provide a key for each one because Vue likes to have the key with your v4s. And the thing that is unique in each of these is probably going to be the message. And then inside of the slot, we will echo the dynamic message here.

Lastly, we will make the type dynamic as well. Cool, this works. Now we have a green alert with the proper message and a red alert with the proper message. Let's print out the alerts right here though, just down below so that we can see what that looks like.

So here is our array with two alerts in it. If I close one of our alerts now though, notice that it still exists inside of the array. This is actually a setup I've seen pretty often in real life apps. what I want to do is listen for the close of the alert and remove that alert from the array so that our data is consistent with what's being shown on the screen.

So I'll get rid of this handle close function that we weren't doing anything with, break this down to a new line so it's a little easier to read, and then we'll say at close we want to set alerts equal to alerts with the closed alert filtered out. So A is the current alert being iterated over. message. Great.

This essentially says return all the ones except the one that was just closed. Now over in the browser, when I close an alert, the error one does disappear and the success is the only one left. If I close the success alert, then it is removed from the array as well. I hope this lesson was helpful to show you yet another practical example of what a component might look like and gave you good hands-on practice defining an alert component using prompts, using emits, and using slots.