Vue 3 Fundamentals

Composables Q&A

Ben Hong

Ben Hong

Vue 3 Fundamentals

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

The "Composables Q&A" 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 answers student questions regarding how beforeDestroy works in Composition API, how permanent the composables are, and how an unmounted component's state is handled.


Transcript from the "Composables Q&A" Lesson

>> Question here in the chat.
>> How do life lifecycle hooks like before destroy or destroy work inside the Composition API?
>> Yeah, this is a great question. So if we look inside of our lifecycle hooks, do I have it already. The way to think about it is that composition API doesn't actually, as much as we're talking about it as like a separate way of architecting your apps, it doesn't break away from how the component works.

So the question here regarding like before unmount, so basically destroy instead of destroyed, think of it as unmounted. All that stuff still happens at the end. The only thing that's different about the composition API is that it just happens at the very beginning. It's still all that other stuff you expect when it comes to destroying stuff, that still factors into composition API.

In fact, composition API will continue to hit all these other lifecycle hooks. So just to answer this question a little bit more fully, let me go to the pokedex here that has the script set up. So if in the event, right, you're saying, Well, this component, right, let's say, let me put the side by side so we can actually see this together.

And then let me reduce that so it's easier to read, okay? So if you're trying to say that like, okay, I have this thing where like right before the component unmount I want it to do something. Sometimes that's the thing, right, before it's destroyed. The way you would do that is you need a helper method.

And so we have, just as you would expect it to be called it's not called before unmount. Because what we realized with conventions is that this is really a lifecycle event. So really all of our stuff are prefixed with on, like you would expect for other events, on click on key up.

Well, since this is a helper method for an event for lifecycle hooks onBeforeMount is what we would import. Sorry, onBeforeUnmount because that's particularly what we were talking about. So we would say onBeforeUnmount. There we go. And then, I usually like to keep my lifecycle hooks towards the bottom usually, but especially with composition API that goes out the window depending on how complex the code is.

So be very clear. That is not at all a best practice just kind of what I use. I'm used to doing from the the Options API. So what we do is we would call onBeforeUnmount. And then it's a function that takes a callback function of what we wanna do.

So in this particular case, you might be like, do this thing. And then that's it. Essentially what you have done in Options API you just defined it at the setup level. So the key thing again to remember is that Composition API does not take you out of the flow.

You're absolutely bought into the whole thing. It's just now you can literally set everything up right here at this one step and then let it run from there. Whereas as we saw with Options API there is kind of a little bit more intricacy regarding do your setup then pass that into your options and then options can do stuff from there.

So it's a style thing, you'll figure out what works best for you. But what I've done in this workshop is try to present you with the different styles so that you can get a feel for it and figure out what you want for your apps. Hopefully, it helps answer that question.

>> The composables. Are they singletons that are around for the lifecycle of the app or if they're not being actively used by components on screen, are they tossed away and then re instantiated fresh next time they're used?
>> This is a good question. All right. So the context set.

The question here, let me go to the base-counter, is around the idea of these composables and whether they're singletons and basically how permanent are they in regards to the entire instance. So, because we're not getting into composable this means you are starting to get into scoping concerns when you're talking about JavaScript, which was talking about like the learning curve for Composition API starts to increment a little bit when you start to think about this stuff.

So to give you an example of this, let's go back to that countStore. Okay, so like any normal JavaScript, what we can also do is we can also instead create something called something like useCount that is a function. And so when you do this though, okay, and let's say we have const localCount = ref of, let's say 50.

And then we return newCount, although let me actually move this a little bit better, globalCount and return localCount. Okay, there we have that. I think I did all this right, perfect, okay. So the other thing I need to do is actually not have this. This is more of like that sort of factory approach to composables, where what you're doing is you're running a function that then has basically.

Well, we're about to see shortly what it looks like, it's easier to show than to explain this in its raw form. Okay, so rather than newCount anymore, we got this function called useCount. So all we can do now is we can say, inside of the function we're going to get the fact that we can do const, okay, actually I did not like the way I've minimized this.

There we go. countStore. Okay, very good. useCount. And then this is log countStore to start. Let's not even return anything just yet, okay. Doo, doo, doo, doo, doo, if we take a look at our console and refresh. Doo, doo, doo. Right. Okay, sorry. It's still looking for newCount in here.

So let me go ahead and comment that out. And then where's newCount? NewCount also exists here inside of UserCard. Let me disable that as well. Not that UserCard, this UserCard. Yep, Yep. And then, this should be hidden too. Okay, now we're good. Okay. So what we see here is that globalCount gets two different refs.

There's a local and a global one. And so, inside of here, if we return countStore to expose it out basically once again. And then what we can do here is, let's do two different buttons now. We're going to have the ability to, right, it's being referenced here. So we're gonna say New counter here.

That's gonna add an extra here that's easier to see. And then let me not clip the browser. Okay, so what I'm gonna do here is when I say Global Count and that's going to be countStore.globalCount, and then Local Count countStore.localCount, okay. So this what we're seeing here matches up to what we have here inside of countStore, right?

So the difference here being that let's go ahead and add some functionality here where if we wanna go ahead and increment stuff, what does that look like? So we're gonna add a button here real quick. And we're just gonna write some inline JavaScript just to make life a little bit easier.

Where globalCount will be incremented by 80. So I'll just call that global. And then we'll do localCount by 100. Although let's make this more jarring, so that's easier. 10 and 100. Local, great. So what we have here, we have the references to it, but we're trying to mutate the count specifically.

And so one of the things we can do instead is because of the way they're scoped, we could do the increment localCount here for example. And here is where we can say localCount.value +=80. Expose increment local count like this. And then since we have that functionality shared, now what we can do is we can say doo, doo, doo, do countStore.incrementLocalCount.

Like that, save, refresh. You see our local is now changing. The reason this is different is if we go back to our UserCard. And let's do the same thing where we import our use count here. And so then we say const countStore = useCount and then return countStore.

And this time, we'll copy this exact snippet over here. So it's very obvious. Save, okay. [COUGH] You'll see a couple of things here. One, because of the way the function instantiates, as you would expect, the localCount, like the component for the base counter actually is holding its own version of that localCount.

While over here we can see that the UserCard has its own version of localCount. On the other hand, if we have a function here that allows us to incrementGlobalCount. And then let's just, once again, globalCount.value+ equals, let's do 1000. Then we'll go ahead and do incrementGlobalCount, great. Now let me go ahead and switch this out.

Doo, doo, doo global, that's good. Then we have this right here, save, refresh. We have Global changing in the top, Global changing both sides. And so I know this was a bit of a long winded answer, but it goes to show that it basically comes down to your ability to scope your JavaScript as you normally would as far as generating those.

>> So what Joe's asking. So let's say you hit a button that rendered different components.
>> Yep.
>> So both the counter and the user are off screen. And then you reinstantiate those two components. Does Global Count start over or is that state held by the app in some way?

>> In that particular case if the component is unmounted and views already tracking the global state, I would imagine the global state would state but the local state would get reinstantiated, that's what you should expect.
>> Okay, [INAUDIBLE] uses it as a singleton for the lifetime of the app.

>> Yep, there might be some gotchas in certain situations, but again, if you run into that, let me know we can always take a look at that, but that probably would go beyond the scope of this. Cool. Okay, so I know there is a lot going on here, but I wanted to kind of provide the full landscape for those who aren't used to writing their own JavaScript modules.

And to actually show you some of the differences behind what happens when you use the function to invoke it versus just exporting a constant and just give you some different options there.

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