Transcript from the "Refactoring Options API Methods" Lesson
>> We've done Options API, these are the core functionality of what most people are using it for. And now it's time to hop on over to the bridge to Composition API. But again, the key thing here is the bridge because we're not gonna go fully into it yet.
[00:00:10] We're gonna see kind of the intermediary and sort of learn the progression from options to composition. All right, so let's take a look at our code. Let me go open up restaurant page, okay? So we've learned that when it comes to integrating TypeScript with object API or options API, we can see here we had to do like define component.
[00:00:49] And that's really where composition API comes into play. And so, the one thing I have to underscore actually a lot right now, which I forgot to animate to you, is that the composition API does not replace the options API. I know people love Buzzwords and things going viral, and I think there was a blog post where I think someone was claiming it at one point.
[00:01:08] So that message did become, it kind of like pervaded throughout, unfortunately. And the options API actually, believe it or not, is something that we can very easily support as the Vue team. Because underlying what we've written, options API is basically one style of writing components. So when people are like, this is gonna go away, it's just a style of writing components.
[00:01:26] There's nothing unique about what's going on there because the composition API and the options API are powered by the same core library. So I just need that to be just keep pushing that message, so people don't feel like, no, my options API is going away. No, it's not.
[00:01:54] So for example, here with data we have this function that's returning an object, and then we have computed properties, we have all these guardrails. Let's take a look at what it might look like inside of composition API instead. And so the way that you know you're inside composition API is through the setup lifecycle hook.
[00:02:11] So for those who come from Vue 2, you might be familiar with mounted, created, all those lifecycle hooks. Setup is the first one that runs at the beginning now of all the component lifecycle methods. And so what we are gonna do is we are just gonna migrate our options API stuff into composition API just to show you where that progression is, so that then later when we take that next jump, it won't be so jarring.
[00:03:01] So think of a reactive reference, that's what that is. So we say, this is going to be a ref that is an empty string, this tells us that, okay, this is gonna be the equivalent of this right here inside of our data. So that's been moved. Next we're gonna go ahead and let's move restaurant lists.
[00:03:19] So shall we? So I'm gonna copy restaurant lists over here, and then I'm gonna const this as well. const restaurantList = a ref that's an array, so this is a reactive array, not array, yes, a reactive array. Okay, finally, we gotta move our showNewForm here. So I'm gonna move that over here and const showNewForm.
[00:03:42] And this is not gonna be false, but this will be a ref of false just like that. And so now that we've deleted all this, you'll notice now that we are in a sort of untyped territory again. Because when we look and hover over filter text, you'll see that now we have this new type that's being inherited called a ref.
[00:04:03] This is a reactive reference, so think of this like when you were looking at options API and you had data, and methods, and all these specific types. This is now saying that, okay, we know how to handle this specific type of ref, which is a reactive reference within Vue.
[00:04:16] And so here you'll see that restaurant lists actually does say, well, actually similarly, let me detect the shape of the objects I'm noticing inside of my array. But we wanna go ahead and say, hey, this is an array of restaurants. So the way that we do this is with typecasting, just like we did before where we say this should be a restaurant array.
[00:04:38] And just like that, now we've gone ahead and actually defined our ref correctly. And so this should start to feel a little bit more like TypeScript. Okay, and then going forward, here we have here we have a ref, this is a Boolean, so we're good on this end.
[00:05:13] In the setup function, you might have some that are private variables, some that you wanna expose. So we want you to be explicit in this particular format of setup when it comes to returning this stuff. So once again, I can return this showNewForm. And now that I have this, everything is now can feed into the options API just like you normally would.
[00:05:31] But again, we're learning more about composition API, so let's continue this journey and migrate everything over. So for computed properties, now we have these reactive references. We have a computer helper method, and this is the computed helper method is just like the ref where we're basically saying this is gonna be a computed property that's based on Vue.
[00:05:52] So here, let's go ahead and grab this. Let's start with number of restaurants, that's the easiest one. So number of restaurants here is going to be a computed property. So this is the helper computed, and it's going to be a function that returns a reactive variable. Now what you'll first notice though, is that it's gonna yell at us because it say, hey, wait a second, where does filteredRestaurantList exists?
[00:07:04] I'm gonna go ahead and just delete this, it should work. It does not work, the reason for that is because reactive references play on basically an object definition syntax for tracking reactivity and proxies, which we're not gonna get into. But basically, when you're using composition API with reactive references, particularly the ref helper, you need to unpack the value.
[00:07:23] Because otherwise, it's just a constant you're working with, this is why there's no filter. And so if we add this .value to our reactive reference, you'll notice that suddenly everything opens up. It knows what the restaurant is, it knows what to grab. And so whenever using ref, basically remember that you have this dot value that you need to unpack.
[00:08:04] Because otherwise, if you use the reactive helper method, which I'll just show you real quick. So if we say like const todoItem = reactive, so this is another helper method where it might be like id: '123'. Although actually, let me just show you the text pastry. Just as a reminder, we can use that and just scaffold that, and then title: 'Get milk', right?
[00:08:27] The reactive object does allow you to just go todoItem.title, and then it just works. But if this were a ref, you do need to do value.title. And so some people will go, well, then I'm just gonna use reactive, and that's totally up to you. Again, I've seen people go both ways on this, it depends on you and your team.
[00:08:45] I'm using ref just because I think that's the one that tends to catch people off guard when they're not used to using it. So I want people to just get a little bit more exposure and so that when you see it, and you're working with it, you're not confused.
[00:08:54] But by all means, if you wanna just use the reactive, that's totally up to you as well. Okay, so now that we have that, we have this other issue, right? Filter text doesn't exist. Well, that makes sense because we need to eliminate this and just add .value that works.
[00:09:10] And once again, delete that .value. There we go. So, now our filteredRestaurantList computed property does work as expected. And you can see here that it actually tells you that, hey, this is actually a type of computed ref. So this is what's really nice about getting into composition API when you're working with Typescript is because you're sure to get a lot more specific as far as how things are being used.
[00:09:33] Whereas an options API, it does depend on where you put it in the code, and then you kinda have to like trigger it a little bit to work the way that you want to with options. This feels a little bit more like natural TypeScript because again, it's just a computer helper method, and then you're defining a callback function inside of here.
[00:09:48] And then you're basically defining the return here, which is the list of restaurants. And then basically, you're good to go. All right, finally here, for a number of restaurants, we have a dependency on the computed property. Now remember what I said, refs require you to unpack it. So when we look at filteredRestaurantList, it is a computed ref.
[00:10:09] In other words, we actually do need to unpack this as well. So this is where .value also needs to come into play. And that's a little gotcha that some people don't realize when you're learning about ref and reactive Is that because computer is using ref, it also needs to be unpacked.
[00:10:23] So then it's saying it's not being used, so let's go ahead and add that real quick. So let's see. filteredRestaurantList and then wait, did I miss type it? I think I did. There you go. And then we have the number of restaurants, okay? Great, all right, that means computed has been successfully migrated.
[00:10:56] So I'm just gonna grab all three here and use a multi cursor editing to save us a little bit of time. And so here, let me just delete that, delete that, okay? So here one, two, three, so we have a const of these three functions, we will declare it like this, and then we'll make it an arrow function.
[00:11:16] And then already basically these are the functions that we're going to be calling, although this got deleted somehow. And then let's go ahead and fix all this up. So there we can delete restaurantList.value switch. hideForm is gonna refer to this hideForm, so there's no point for this. And then once again, we can grab that, switch it out to .value, this also .value.
[00:11:43] Great, and so you see here actually, this is, again we're TypeScript can be super helpful is that without the .value if you forget to unpack it. You can see already that it says that I don't know what I'm unpacking here, there's an any here for some reason. And so that yelling at me reminds me I need the value.
[00:11:58] Great, and then once again, showNewForm is just a ref. So there we go. And then we need to expose all this stuff, so deleteRestaurant hideForm. And then the last one was addRestaurant, okay? Finally, one last bit as we migrate this over is that we need the ability to call the mounted life cycle hook because we're again, I wanna show that transition over.
[00:12:27] So one of the things we've done as a convention inside of Vue is that we provided you helper methods, right? That's what we've been doing this whole time, ref computed all that stuff. So we have this thing called, basically life-cycle hooks, so onMounted which is a life-cycle hook that we can import as you can see here, it's being imported directly from Vue.
[00:12:46] This is what actually allows us to then call those lifecycle hooks. So onMounted here, and then we basically pass in the callback function that will run on that specific one. What are we gonna do? Okay, so this is where some people get tripped up because this is where we now sort of enter the land of composable.
[00:13:05] If you haven't heard that term before, basically it's a unique term to any sort of composition API module. So anytime someone uses a function that creates like an example like router, any sort of function, it uses composition API. They're currently being termed as composable because they're external modules that use composition API.
[00:13:24] I don't know, I have mixed feelings on the name, but it seems to be sticking, so that's what it is. And so in this particular case, you'll notice that onMounted what we're doing here is we're checking for the route. And if the route has a query parameter of new, we're actually showing the new form basically.
[00:13:41] So it's like a hack over rather doing direct routing. So how do we actually get this, right? Because now there's no more global properties. This is one of the things I think that scares people a little bit when moving from options API to composition API is that there's a lot of guardrails that options this gives you automatically, especially when it comes to globally inherited stuff.
[00:14:00] And so the way this works actually is that, especially with Vue 3 going forward, with all the libraries being TypeScript friendly, and we wanna be composition API friendly. In addition to being options API friendly, is that we have this prefix in composable that's being used a lot, inadvertently called use.
[00:14:16] So what we can do is, since we wanna grab the link from the route, we wanna grab something from Vue router. So if I scroll up here, I can import something called useRoute from vue router. And so if you're thinking of like, well, how would I know to use like use route?
[00:14:33] We try to actually follow conventions of what you would expect from the global API. So sometimes you might want router things, so that will be used router, right, if you see using this .$ router. So use routes here is what's gonna basically allow you to get all the things that you would normally get from this .$.route.
[00:14:50] So if I do useRoute like this, this will actually then grab the route for me. And then I can swap this out now which is route, and then I can swap this out with .value. And that is everything when it comes to migrating to the composition API. And so as we can see now, we can actually delete this part here.
[00:15:33] So in the past, right, this is essentially the methods section. This was the lifecycle section, and then we had computed here. And then we had all our data here. But because we're in free form composition API then, we can actually start thinking like, you know what, actually, I think it makes more sense to group all like the restaurant stuff together.
[00:15:56] So I'm gonna take the restaurant here, group that with this, cuz I think this makes more sense that we established the ref. First, I'm gonna call this Restaurant Module, we have the list of data, we filter that data, and then we can even manage that data. So I can do like that.
[00:16:12] And then number of restaurants actually is relevant, so we'll keep it there. But then we have all this form stuff, right, and this stuff we can really just say this is the New Form Module. And then we can just say, well, for now the life cycle hook is related to this if not doing anything else different with it.
[00:17:21] But because everything here in composition API is very declarative, you know exactly when you're importing something from a specific file, what it's being named, or you can rename it if it has a conflict with that specific file. And you don't have to deal with all the assumptions that the options API can often provide for you, which again, can be helpful in certain contexts.
[00:17:38] But in the context of reusability of code, the mixins definitely became a fun one for a lot of people that we learned.