Vue 3 Fundamentals

Custom Components

Ben Hong

Ben Hong

Vue 3 Fundamentals

Check out a free preview of the full Vue 3 Fundamentals course

The "Custom Components" Lesson is part of the full, Vue 3 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Ben demonstrates creating a custom component in Vue and scoping all of the associated JavaScript and HTML to that specific file. Components are pulled into the application by registering them in the exports under the components option.


Transcript from the "Custom Components" Lesson

>> We've been talking about single file components. And it's really time for us to really start diving into it. Because what we've really done is basically moved our entire app from index.html into app.vue. But this code, there's a lot going on here, right? Especially, cuz there's a lot of logic and more importantly, things can be scoped kinda differently.

So it's time to really dive into component-driven development at this point. Okay, so for what I'm gonna do here, I'm gonna delete all the boilerplate inside of our code base here. So that we're not dealing with any boilerplate. So let me go ahead and refactor that real quick.

Factor: delete boilerplate components, okay. So now, let's talk about how we actually create components in Vue. As we mentioned, single file components are basically the way to go. So let's start with something like the, let's start with something simple. Actually, I'm in the wrong directory for this. Let's go back to the playground, cuz we'll use the exercise for that.

Okay, inside of my playground, let's take a look at this one. So now, that we're actually in the build tool though, I need to actually make sure I run the right one. So I'll go back to my playground app and run dev. And so now, that we're running it, there we go.

We see that it automatically refreshed without me doing anything, so this is great, we have the update. All right, so let's take a look at what's going on inside of our app here. There is a lot, we've played around with different concepts, we talked about lists of numbers, we talked about this increment thing.

So basically, let's start with the simplest thing, which is that we have a counter component. That's like the easiest thing that we could split off from this at this point. And so what we can do then is we can say, okay, let's go into the components folder. And let's create a new one called counter.view, okay?

So I'm gonna go ahead and full screen this, so that it's easier to see, since we don't actually need to see the live updates right now. When you're creating a new component, basically, we have our basic building blocks. We have our script block and we have our template block.

We don't have any custom styling right now. So I'm not gonna add anything. And so let's start moving some stuff over. So what I would do is I would actually start by saying, okay, so inside of my script block, I will export a default object, cuz this is what I'm configuring.

And so inside of my data, what do we have that we wanna migrate over? Well, we care about the count, so that looks good. The counter title, yeah, that sounds good too. And we care about the incrementAmount, this is good. And then listOfNumbers's not relevant. Okay, okay, we have some computed properties, that's relevant for displayTitle and optimizedIncrementAmount.

So actually none of this is related to anything else, right? Cuz we have the count, which is here, we have the displayTitle, which is here, and the incrementalAmount is here. Meaning, we can take this whole block actually and just cut that from the app.view, and then we can put it here.

And then finally, we have this increment count method that we're using. And we're actually not even using the watch. So we can actually delete this and we can cut the methods entire block over. And then what you'll see that we end up having here is that we have all of our logic now scoped to the counter, right?

Nothing that's relevant to it is kept to it and this is great, right? And to be clear, this is not a view thing like, React Angular. We've all been basically thinking this way as far as like keeping our concerns scope to the same file. So it's easier for people to understand.

You don't have to jump files as much. Now, of course, we've got to make sure we move all the stuff that's related though to the counter app when it comes to HTML. So we have that here, here, here, here. I think I mostly organized it together, so there's not too much mystery there.

And so I can cut all that and just drop it over here inside of the template. And so what you got here now is we have our scoped JavaScript and HTML. And so now, it's the time where we actually kind of wanna see what's going on inside of the app.

And so if we take a look, you'll notice our counter app is gone. And that's to be expected, because we've already moved everything. But what we haven't done is we haven't actually called our component. So how does that actually work? Well, just like standard JavaScript, what we wanna do is we wanna basically import our component.

So we wanna import our counter component where are we importing it from? Well, we're gonna move up a directory, cuz right now we're in app.vue. We're gonna move, wait counter is in the wrong one right now. It needs to move down here, okay. So we have our app.vue and we're gonna import counter.

And so this is following the file path directory where we have the root directory which is this flat one right here, I'm gonna go up into components. And then we're gonna import counter.vue, it's all we're gonna do. You'll notice that our extensions are yelling at us, because why is saying hey, you import something you never ever used it?

And so the way we actually register a component inside of use option API is well, there is an aptly called components option, where we can basically register our counter just like that. And then-
>> Your methods is inside of your computer's encounter?
>> Computed, yeah, you're totally right.

So the observation was pointed out here that my methods when I copy and pasted was copy pasted at the wrong point. So we should actually move this out. There you go, now, that looks much better. [SOUND] Yeah, that's another thing we'll talk about in a second. Okay, there we go, we have counter and this is good.

And then now, we need to actually use it, how to use it? Well, it's a custom component. So whatever we named it, basically, we'll do the trick. And so there we go, there's our counter component. A couple of things that might be new if you're haven't really worked with components before, is that this is what's called a self-closing tag.

So this is the equivalent of doing this. It's just a little bit more succinct, because rather than duplicating it over, it's fairly combed as a self-enclosed like this. In addition, something else that view tries to get you to do though, before we talk more about this is you'll notice that earlier I had this error.

Which is from es lint in that we really tried to recommend that you use multiword component names. And the reason for that is because you never know when the HTML spec is going to add something. And they basically have, they get first dibs when it comes to one word components.

So rather than basically run the risk of conflicting that, what I might do instead is I might call this like base counter, right? This is like the the counter to rule all components. And so you'll notice here though that volar, hey, it says, I noticed you're refactoring some stuff.

And you say, what do you what did you notice? And it says, look, I noticed that inside of here, it'll actually track the file path of the thing that it's related to which is pretty cool. So I can go ahead and apply that and now, you'll see that instead of app.vue it's gone ahead and actually renamed it correctly inside of my imports.

Which is a nice optimization that it does for us. But once again, I really would like to avoid the single word naming. So I'm just gonna do that like that. And then you'll see everything still works as expected. But another thing that view does for you in terms of extending upon HTML standards is, you might not like the Pascal case, which is where you have the multiword capitalized.

And you might say, I would rather just do like the standard kebab case for HTML. And believe it or not, that actually just works. Vue will out of the box basically allow you to convert between two cases, because it knows how to track the differences. And so to say which one is better?

It depends a lot on the team that you're working with. I would say in terms of pros and cons. One of the nice thing about the Pascal case is that it becomes very evident that this is something very specific to the app that this is something custom. Granted, if using a multiword component, that also kind of does the job as well.

So it's just kind of what you're used to in that regard. You have a question?
>> The inverse of that work, can you name the file kebab case?
>> I should be able to, let's give that a shot. So the question was, can we name the file kebab case?

Like that, and then what did it change, well, here we go, notice that we have applied that, so we can apply that. And then inside of here, we're good inside of here. This we can do anything about, cuz this is like an import. And then I think that actually still works.

Yep, that's the works. The main thing about that is be consistent, that's the only thing I asked. It doesn't matter which one you choose, just be consistent.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now