Playing
01. Dynamic Vue Components

Episodes

0%
Your progress
  • Total: 12m
  • Played: 0m
  • Remaining: 12m
Join or sign in to track your progress

Transcript

00:00
If you have repeatable components that vary slightly, I'm going to give you a tip now to work with dynamic components in Vue.js and this can massively clean up your code and also make it a lot easier to adapt and add to later.
00:16
So we're going to take the example of a notifications feed. Now from an API, I've just mocked out a really simple assignment here for some notifications. You may get something back from your endpoint that looks like this, your API endpoint. So for example, I've got a notification here which is a post replied notification, so someone
00:38
has replied to someone's post and of course you would have more data than this but just for now we're working with a user in here. The second notification which is still the same type of thing but you would want to represent this slightly differently, add different text, would be say a post being upvoted.
00:55
So the problem here is that we want to render a single notification component but we want to vary what that component says inside of it based on the type. So we'll build this up very slightly and then we'll take a look at the problems that we're going to see.
01:12
Of course, one of the solutions would be to just create some kind of div here, do a V4 on this, iterate through and then have a load of VIFs in here depending on the type. But that would, of course, get very, very slowly messy. You would end up with a huge list of potential things being rendered based on that type.
01:34
If you had 100 notification types, you would have 100 different if statements in here all checking for different types. So what we're going to do is we're going to start over in our components directory because we're going to create a common app notification wrapper for any notification that we find
01:52
in our application. So let's just start to build this out. I'm going to create a div in here with a class of notification. Of course, we're not applying any styling or anything here.
02:00
So I'm just going to go ahead and add in a notification target and I'm going to set the margin on the bottom just here to, let's say, 40 pixels. It doesn't really matter. So inside of here, we would probably want a common action associated with each of our
02:16
notifications. This is where things start to get tricky because you want to display something different for a notification but you still want the same wrapper. You still want a marker's red button and all of that good stuff.
02:28
So inside of here, we're going to introduce a slot. If you're not aware of slots, it just allows you to render this component but this default slot means that you can place any content you want inside of here. So this is just our overall notification wrapper.
02:41
So let's go ahead and just import this from here. So import app notification and we'll pull that in from the components directory. So app notification. In fact, let's stick this inside of a notifications folder just to make things a little bit easier.
02:57
Okay, great. So we can go ahead and register this component and, of course, we can iterate over this. So we'll render this component out. We will not make it a self-closing component because remember the data that we want with
03:09
the varied component will go in the middle and we'll just do a V4 over our notification. So for each notification in notifications, let's go ahead and give this a key. I've just added a simple ID onto this. And then inside of here will be the text that we want to render out.
03:25
So heading over to the browser, we get exactly what we expect. We've got this slot data that we've just placed in here and exactly the same structure to each of them notifications. So now what I want to do is the first option would be to perhaps create a template in here
03:40
and then say VIF notification type equals. And let's just take a look at what kind of data we've got down here. So post replied. So if it's a post replied, we'd want to go ahead and inject in so-and-so replied to your
03:56
post and we would swap this out for that notification user. So notification user name. Otherwise, we could go ahead and if it's post upvoted, say upvoted your post and so on and so forth.
04:12
So that does the job. But like I said, if you have a hundred different notification types, of course, you're going to end up with a huge mess inside of here. Now, of course, the other option is to render this out to tidy up slightly as a new component.
04:27
So what I would typically do is create some kind of types folder in here. And then I would create a new component for each of these types. And this is the beginning of creating them dynamic components. So I would create a app notification post replied dot view component.
04:43
And I would do more or less the same thing if we just grab the name of this for the app notification post upvoted component. So inside of each of these, we can now create our template. We can bring over the content that we would normally render in here.
05:00
So let's just pop that in a paragraph. And of course, we can accept props into this now, which makes it a little bit tidier. And we can get rid of the actual content of this inside of here. So if we go ahead and just pull in app notification post replied and pull that in from that types
05:16
directory, and we'll do the same thing for post upvoted as well. And we'll give this a very similar structure like so. Just by the way, the reason that I am using app notification post replied is just based on views style guide.
05:32
By prefixing this, you're not creating an element which won't potentially exist in the future within the HTML specification. Because of course, these are almost representing HTML tags. Very unlikely, but I always prefix these anyway just to make sure.
05:48
Okay, so with that said, let's go and render out an app notification post replied component. Let's go ahead and pass through the notification so we can use that data. And of course, this will only be rendered out if we have a notification type of post replied.
06:07
So again, let's do exactly the same thing. It's looking a little bit better, but it's still not great. We've got post replied, post upvoted, and we'll change that condition just over there as well.
06:19
So let's go and over to post replied, just switch this over to here and say upvoted your post. And if we just make sure that the ending tags are on here, because we don't need any slot data passed through to that, we should see more or less exactly the same thing.
06:34
Of course, we don't see anything at the moment because we're not accepting the props into here. So let's do that now just very, very quickly. And then we'll get onto the dynamic component that we came here for.
06:44
So let's just to find out that we want a notification prop in here. This is going to be required because we need that data. So let's set that to true and we'll give a type of object just so we typecast this. So let's go and grab the script for this, pop it over to here.
07:00
And essentially what we now have is a repeatable component that we can use. It's not entirely tied down to this notification. We're slotting each of these in, but these are now free to do whatever you want with. You can just go ahead and modify this.
07:14
You can link through to places. You can add something slightly different for a slightly different notification if you need to. So now you can see that works in exactly the same way.
07:24
But once again, if you have 100 or so notifications, you're going to end up with a huge long list like this. And it's not very nice updating something like this, having to re-import the component, then output it here, add the if statement, pass the prop through.
07:39
It's going to get very, very tricky. So what we're going to do is scrap this all together and we're going to look at one way of pulling in dynamic view components and then a slightly better way. Now let's say that we had in an ideal world the type of notification as post replied.
07:56
Now I wouldn't for a moment suggest that you change the data that you're working with in your API to assist your client. It should never be that way. It should be just generic data that could be used with anything.
08:08
We don't want to specifically send through data from our API that's going to help us out specifically with a view application. But just imagine that we did do that and we had post replied and post upvoted. This is a nice kind of format and standard for a component name.
08:26
You can see that post replied matches this last part of this component and post upvoted matches this last part of this component. So what we can do now is generate out or create or render a dynamic component. And to do this, we just use the component like this.
08:42
We just use component on its own. Now the way that we specify which component we want to render is by using is and then passing the name of the component in here. So just to demonstrate this, I'm going to pop the name of the component in here.
08:56
So let's just wrap that in backticks. And that will go ahead and render out that specific component. And because we're rendering out that specific component, we also still need to pass that prop down into it.
09:06
So we still need that notification in there. And if we just give this a refresh and just end that component tag, you can see that we get exactly the same thing that we had before. The only difference now is I'm hard coding post replied, whereas one of these is not
09:21
post replied, it's post upvoted. So what we want to do is take this part of here, chop this off, and dynamically pop in here the notification type, which remember is exactly how we want it. So as you can see here, this works beautifully.
09:38
And now when we want to create a new notification type, all we need to do is pull this into here, register it, and we're done. And of course, actually create the component itself. We don't need to add another if statement here.
09:53
And this is as big as this is going to get. Now the only issue with this approach is that this, of course, matches the component name exactly. We're going to bring it back to post replied.
10:06
And I'm going to bring this back to post upvoted. And let's just see what happens when we do this. Of course, if we open up our console, we're going to see an issue where this notification post hyphen replied component does not exist.
10:20
Now there's one way to do this, and that is to change over the names of your components. But we're not going to quite do that. It's going to look a little bit messy. And if we've got hyphens in there, we're not exactly going to use hyphens inside of here.
10:32
It's just not going to work. So what we can actually do is we can scrap the prefix here altogether. And we can just say that we want to render out a component called notification type. Now this isn't going to work as well, of course, because the post replied component doesn't
10:48
exist. So how can we get around this? Well, when we create a new component and bring this in, what we can actually do is under this components object here, we can go ahead and give these names.
10:59
So I can say, well, post replied should match up with that post replied piece of data I'm getting back from my API. And exactly the same as well with post upvoted. So what we're doing is we're creating a kind of section of components here, which are purely
11:14
for the fact that we want to render these based out on the notification. And when I give that a refresh, sure enough, you see we get exactly the same result. So a really, really simple tip there to use a dynamic component is incredibly helpful for repeatable things, but things that need to slightly change like notifications.
11:34
I've not used these for any other type of thing. I've only used these for notifications, but I'm sure they have many other uses as well. But I've shown you how to do this originally, how to potentially do this if you have matching data, but really the best way is to go ahead and specify the component name just inside
11:51
of here. So now anytime we get a new notification type, all we need to do is create the component, import it, match it up with the tag, and we are done. That's going to work beautifully.
1 episode 12 mins

Overview

Vue allows you to dynamically render components based on their names. This can help simplify your rendering and get rid of unnecessary logic from your templates. Here's an example using different notification types.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!