Production-Grade Vue.js Production-Grade Vue.js

Solving Prop Complexity with Slots

Check out a free preview of the full Production-Grade Vue.js course:
The "Solving Prop Complexity with Slots" Lesson is part of the full, Production-Grade Vue.js course featured in this preview video. Here's what you'd learn in this lesson:

Ben uses a thought-exercise to explain how using too many props can increase the technical debt of a component. Slots simplify the complexity by allowing content to be injected into a component from its parent.

Get Unlimited Access Now

Transcript from the "Solving Prop Complexity with Slots" Lesson

[00:00:00]
>> All right, so let's do a little coding experiment. Credit goes to Damien and Delish, who's on the core team, also known as Shentel and GitHub for orchestrating one of the original versions of this, all right. So I want you to do is in your head, you're gonna, you don't have to code this out so this is all in your head.

[00:00:16] Task number 1, I want you to create a button component that can display texts in the parent component. You'll see that, actually shoot, you'll see that there's the example right in the middle of the submit button. So go ahead and sketch that out in your head, how you might do that base button component.

[00:00:35] Okay, now that you have, I assume you have something basic, wanna go on. I want you to go ahead and the button needs to be able to display an icon of your choice on the right side of the text. So as we see in the middle, you have the submit button with that right arrow, and assume that you already have a base component called app icon.

[00:00:54] That's what you're gonna include inside of the HTML. So, give you a few seconds for that. Okay, now product has a new requirement actually, they want you to be able to do icons on either sides of the button. So go ahead and code that up in your head.

[00:01:22] Now we have an additional requirement from design where we actually need to be able to replace the content with a spinner when the user clicks on it. So you can see now that again, envision you actually have a pulse loader icon that allows you to swap it in and out.

[00:01:35] So go ahead and enhance your button with this loading spinner concept. Okay, I think hopefully you have something there and then task five. Sometimes they want the whole text to replace and other times they just want to replace the icon on the right hand side. So go ahead and like think of how you might do that.

[00:01:59] Okay, don't worry if you couldn't do the whole thing in your head, it's more of a just a mental exercise and the feeling for it. So when we all first started out, I imagine some of you started with something like this, right? We have our template with the type of button and then we have a text that takes the props of text.

[00:02:16] This is fairly straightforward, everyone can understand. But as the requirement start layering on and on kind of looks like this. And it's kind of crazy because all of a sudden it's basically my God, there's props everywhere and it's so hard to track. So we're gonna watch that one more time.

[00:02:36] So that's just satisfying. Yes, [LAUGH]. So it's crazy though, right because what should be so simple as a base button, has suddenly become this crazy thing that like, I don't know about you. I wouldn't wanna manage that component that just seems crazy, I feel like I would break it so easily.

[00:02:54] And so, let's call it the prop based solution to this little mental exercise. And so of course, you're thinking like, is does that mean it's wrong? And the answer is no, it's not wrong. It does the job right. You fulfilled the requirement from product and you got it working but is it good?

[00:03:15] Well, not exactly right. As we can see, if we keep layering on requirements onto this button, it's just gonna be a mess. And so some of the problems with this are that new requirements constantly increased complexity. And what starts out as a simple button with a prop of text has now become this crazy thing where the props, objects and text, even if you define it perfectly.

[00:03:41] Basically means that whenever a new developer wants to come along and use base button, they're basically gonna have to read a dictionary of an API spec on how to use your button. And, again, we want to create components that are intuitive and easy to use, and so I would ideally like to prevent when we're creating components at scale, reducing that barrier.

[00:04:03] And learning obstacle is key to ensuring that it reduces that complexity and that more people can use it and it's actually reusable. Because you can imagine, right, otherwise, if people look at this base button going forward, they're probably goona go, you know what, I'm just gonna create my own button.

[00:04:17] I'm not dealing with this and all sudden you have this fragmented ecosystem where this one button does a lot of things, but no one wants to touch it anymore. And so then they just create their own buttons. And that's just, that's clearly technical debt and a fracture inside of your architecture.

[00:04:32] And so, as we can see, there are a lot of responsibilities, templates in the conditional and it's just super complicated. And so since this solution isn't the best, is there a better alternative? And this being view, of course there is, we always try to provide new solutions when you need them.

[00:04:53] And so, the better solution is to use, right, I forgot in the words of service name obviously, there is a better solution. And that is to use slots, and so for those who haven't use slots before, I recommend checking out the docs for how they work but basically think of it an HTML element.

[00:05:13] So, if I were to just show this in live code for a second. When you have something with slots like a base button, right, so I'm just gonna go ahead and write this up real quick. So we have a button here with the slot. All this really says is I want you to accept anything that would come in between this component.

[00:05:34] So let me just do this a little bit more formally. So we have our based upon that view. And so here, right, what base button allows you to do, because you're using a slot is to rather than define everything as props. It means that everything that is provided inside of our tags will actually be passed through into the child.

[00:05:55] So you wanna call it submit. This is great. You will actually get a button that submits has the text submit. But if we need an icon, no problem, app icon icon equals, right for example. And then in the event that we need a button that can be on the left that's not a problem either.

[00:06:13] All you got to do is swap it over to the other side and this would still work granted I mess that up. And so slots are an extremely powerful technique in view. So if you haven't gotten a chance to check it out, definitely look into the docs. Again, there's a whole, we could spend all day on slots and advanced slot technique usage, but it is a very useful tool to have in your tool belt when creating reusable components.

[00:06:37] So just want to keep this in mind.