Vue 3 Fundamentals Custom Components Exercise
Transcript from the "Custom Components Exercise" Lesson
>> Now that we've done that, we have the first component. Let's go ahead and let you all play around with creating your own components from your app. So the exercise here is to basically go inside of your forum app. So whether it's the office, or community, or whatever.
[00:00:19] And then, look at your index.html file, and go. Okay, I wanna create some components out of this, how will I do it? And to give some preface as well, you will run into a limitation pretty quickly, as far as things that you wanna do with it. But, I wanna just get you in the practice of creating some.vue files, and just know that it'll functionally be broken until we get back together.
[00:00:39] But I just wanna get you all in the habit of practicing that. Does that sound good? So you're basically try scoping, bringing stuff together. Let's see how that goes. Okay, welcome back everyone. So hopefully you all had some fun creating components, but I was kind of walking around and checking how people were doing, you probably ran into a problem basically as you started migrating stuff because a lot of your code is dependent on one another.
[00:01:09] And so you might have noticed up instead of moving stuff that it was like being like wait, where's this thing you reference to and like had trouble talking to each other. So let's go and show you what I mean by that. So let me start by opening up my App.vue for my Avatar Last Airbender.
[00:01:27] And so, as we can see here, we have a couple of sections here that could really make sense. We see a bunch of h2's, they could make sense as components, to be totally honest. As far as like these are the characters, this is the character list. And so let's actually try something as simple as that.
[00:01:43] Let's go ahead and start by inside of our components. Let's create a characterList.vue. Okay, and I'm gonna bring this over. And then we have our script block that we're gonna have, and we're gonna have our template block. This time I'm gonna flip it a bit, and we're gonna start by bringing over all the HTML.
[00:02:04] So the H2 up until this point, is all to do with the characters, okay? So if you save that, a lot of stuff is gonna be missing, but that's totally fine. And let's just say placeholder for character list. And then up here, this is where it gets a little bit tricky now.
[00:02:23] Okay, what do we wanna do? Well, we know that characterList here is relevant, so let's start by exporting a default object cuz this is the object that defines our app. So characterList is here. Great, let's do that. So oops, I need my data property, and then I can put my character list in here, awesome.
[00:02:42] And then let's see, what else we got? Well, we have that. We have length, this is pretty good. Actually, this is, actually here. We have a favorite character, okay? How do we do that? Let's see this go here. Yes, we have a method here for favorite character. So I'm just gonna copy the whole block knowing that I would delete the add new character.
[00:03:05] And this is probably what you started doing. And then you're like, yes, there's also this.favoritelist. And then we're like, okay, let's add that to here favoriteList and then we save, and then you're thinking okay, great. I'm gonna import characterList from components.characterlist.vue, okay. That's that, and then you're like I'm gonna register my component at characterList, just like that.
[00:03:36] Okay, and then, oops, this needs to be renamed properly. And then you probably came in and was like okay, I'm gonna try to call my characterList component inside of here. Now if we take a look at what's happening here, so let me go ahead and close this. And then we're gonna go ahead and get out of this go over to our atla-forum.
[00:04:01] Run that dev, great. You're probably gonna realize very shortly that nothing is working. Anyone have any guesses as to why nothing is working?
>> Cuz your parent app relies on the hairstylist for the benderStatistics.
>> Okay, so as we can see here, we actually are relying on inside of App.vue, sorry let's, I technically move this at this point.
[00:04:32] We're actually trying to reference this characterList property, but you'll notice it's gone, and this is what I was mentioning earlier. When you have components scoped, the data are scoped to the component. It's not scoped to the entire app. So in other words, this whole characterList component, which I made based on impulse, actually, if we think about data flow, it's the wrong way.
[00:04:55] Because the characterList is actually basically at the top. That's the thing that serves everything else. So let's rethink that over again, because what we really want is the ability to have the app pushed down into child components, right, single direction data flow is a very big topic these days because it helps to basically ensure that things are easier to track.
[00:05:17] I know that was one of the initial blowbacks when it came to two-way binding, is that people were confused about which way data was flowing. But that doesn't make two-way data binding like wrong, in it of itself, right? We can see that when it's done in an encapsulated way.
[00:05:29] That's easy to understand, it's great. But when it comes to long data flows, we found as an industry that unidirectional data flow basically from top down is like keeping that consistent for the most part has been very helpful for making things maintainable and easier to basically work on.
[00:05:47] Okay, so actually what I've done here as an exercise is an exercise in futility. So I'm gonna go ahead and clear these changes and we're gonna go ahead and take a look how we should be thinking about componentizing our app. So I can go ahead and delete this, and then we can refresh the app now.
[00:06:10] Okay, everything should be working. I think I made everything crash. Okay, refresh. Okay, everything's good. Okay, so the way to think about components is really the component tree. Again, your App.vue is at the very top, everything else goes down from that. So let's pick something smaller to refractor to kind of show you what I mean.
[00:06:31] The easiest thing for here, it looks like is actually probably the statistics module that we had just built. Because really, it has the one computed property here, and then after that, that's basically it. There's not really any other dependency, so this is a nice, small, encapsulated one that we can practice on.
[00:06:48] So here I'll sell it benderStatistics.vue. And this time I blow it up to the side since we're not worried about how it looks right now. And so what we wanna go ahead and do is go and see what that looks like. So first I'm gonna grab the template, doo doo doo.
[00:07:03] There we go. And the template is this short blog. It's just this h2 statistics. And as well we're going to loop through and find this benderStatistics. Okay, so now we need that data property, script. And the data property we're looking for here is benderStatistics here. And it looks like this is the only computed property in this entire app, so we can actually just cut the whole thing.
[00:07:27] And we can export our default object and paste in our computed property, which is great, okay? Now, this is feeling better. However, as you mentioned before, we still have a block, in that, if we go ahead and open this up inside of V right now, so if I save, you'll notice that one, it's fine, right?
[00:07:47] The benderStatistics doesn't show up, no errors, and that's to be expected because, well, we're not calling anything. But, when we add import benderStatistics. And so that was an autocomplete by the way, no magic there, just it's reading it. There we go. We can register it. So components, BenderStatistics.
[00:08:08] Then we can try to call it by rendering it out here. Okay, boom, big error, why? Because if we look inside of the for each, what's it looking for? Is looking for characterList, doesn't exist, right? So now we've proven both ways that data just doesn't magically get scoped out.
[00:08:28] And that again, this is a good thing, because you want things to inherently be scoped to the context in which they're in.