Vue 3 Composition API Introduction [FULL TUTORIAL]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
The biggest new feature introduced by Vue 3 is the so-called Composition API. It's 100% optional and it's an alternative to the Options API. Now, the Options API is simply what we used thus far for building Vue apps and components. When you configure a component like this with a data and methods option, that's using the Options API. You're passing or you are setting various options in the config object of that Vue instance of this Vue component. This approach is absolutely fine. It's not going anywhere and you can stick to it. That's really important to me. But we've now got an alternative to that. You can replace data, methods, computed and watch with a different option, with a different approach and that would be the Composition API. Because you might face too main limitations or issues when building bigger Vue apps with the Options API. For one, code that belongs together logically might be split up across multiple different options across data methods and computed. I actually got an example here, which is not the example we'll dive in in this video. This is taken from my Vue course where I completely updated it to Vue 3. And here I, for example, I got a couple of components and in the UserList component here, I have some data where I manage my users but also a SearchTerm entered by the user and a sorting logic chosen by the user. And then I have computed property for deriving the displayedUsers based on the sorting logic that was chosen by the user of this app. And I also have a search method, so a method related to searching. A method related to sorting. I've got a watcher related to searching. Another watcher related to searching. And as you can see, that logic is kind of split up, right? We've got search data here in the data option. We've got a search method, we've got search watchers and for sorting, we've also got an option, a computed property, data, it's all over the place. This is not horrible necessarily but in bigger applications and bigger components, it may result in a lot of scrolling to update your search logic. If I change something here, let's say the name of the enteredSearchTerm, I have to change it in a couple of places. And such big components where everything is scattered out could become hard or difficult to manage. In addition, reusing logic across components can also be tricky or cumbersome. Here in this demo app, which you find in my course, I do have the ProjectsList component, in addition to the UserList and there I also got search logic. Now, we could share this code maybe with a mix in, but with a mix in, we would face new difficulties. For example, it wouldn't be obvious where this logic is coming from. We would have to look into all mix ins, if we're using multiple mix ins to find out which mix in is holding the search logic. That can also be tricky in bigger applications. So these are not technical problems. These might even be problems for you which you've ever faced and then of course, everything is fine but this could be problems you face in bigger Vue apps and bigger Vue components. And that's why you could move from the Options API to the new Composition API, which merges data methods computed into one setup method, which you still add to your component config object where you then use new features to manage it all and to solve these two problems. So to see this in action, I also prepared a little project for us here. You find a link attached to this video in the video description to this entire repository of all the changed, which I also cover in another video and here in this video, I wanna dive into this composition-api folder. Once you navigated into this folder, run npm install and npm run serve to install all dependencies and bring up the development server. And then you'll see a little application, which I prepared, which uses the Options API, which still works with Vue 3. Here is the app I prepared. I can enter some goals like learn Vue. Explore the new Vue 3 course. But if you enter something like learn React, then this won't show up here because I actually have some logic in there to filter for Angular and React and remove such goals that include these terms. That's the little app we have here. I'm using one component in my App.vue file and that's the CourseGoals component. And there I used two other components, GoalsList and AddGoal. I'm managing some data here in CourseGoals. I have a computed property for filtering my goals for Angular and React. And I have methods for adding a goal to be precise. One method which creates a new goal and adds it to the data property. In AddGoal, I have some data for the enteredText and for the validity of the input. I get the addGoal method where I check the validity and possibly set this to true so that this error message is shown and ultimately, if everything is okay, I emit a custom event with the enteredText and reset the enteredText thereafter. And the enteredText data is bound to this input with v-model, so with two-way binding. In addition, I got a watcher where I watch for invalid input and simply log that to the console. In GoalsList, I got nothing special. Here I just take a prop and output my list items. Now, I'm using the Options API here and now I wanna migrate to the Composition API. And let's maybe start with CourseGoals. As I mentioned, we're going to replace data computed and methods with something new. So I'm going to comment it out. And we're going to replace it with this setup method, which you can now add to your component config objects. Setup is automatically called by Vue when it creates this Vue component. It's called around the same time when the created lifecycle hook would normally be executed. Now, in here, you have to set everything up this component needs. All the data, all the computed properties, all the functions and all the watchers. Now, how do we do that since we don't have these options anymore? Well data can be replaced with refs, for example, and you need to import something from Vue for that. So import from vue and what we import between curly braces here is the ref function. Ref is simply a reactive piece of data you could say. You create such a reactive piece of data by calling ref in setup. It's basically creating a JavaScript variable, you could say, but one where Vue is aware of any changes made to it. And where Vue then is able to update the template if such a change is detected. A ref can take a default value. So here, since I wanna replace goals, ultimately I'll pass in an array. Now we can store this ref, this reactive variable in a constant or variable and I'll name it goals. And a constant is enough here because we'll never assign a new value to this. We can change the values stored in a ref but behind the scenes, the ref will create a wrapper object around this array, so we'll only change the wrapped value, not the entire ref object. And with that, we've got our reactive variable, which holds this array, which, and that's important, is known by Vue and where when we change this array, Vue will be aware of those changes and if we use this array in the template, it will then know where to update the template. So that's one important step. This is how we can replace our data. There's also another way of replacing data. There also is a reactive function, which you could use but I'll not dive into this here. I cover it in detail in my course if you're interested in that but refs are what I use most commonly and you can use them for pretty much everything, so here that's all we need. Now we need to one important thing here in setup. We need to let Vue know about the things it should be able to use in the template. Setup needs to return what should be available in the template and that always is an object where you now map the different things you have in setup, like this goals ref, to identifiers of your choice. It can be the same name, goals, or something totally different like this. And these keys here can now be used in your template of this component. So for example, now I can use userGoals here instead of filteredGoals if I wanted to. I don't want to but we could do this. Now, we actually don't need goals like this in the template though because we just used the computed property in the past. So I'm actually not going to expose it but we're going to add things to this object soon. Let's maybe continue with this computed property then. How do we create this when using setup and the Composition API? Well, we import another function from Vue. The computed function, which is used to create computed properties. You simply call computed and then pass a function to it. This function has to return a value, the value of your computed property, and here, for example, I can use the same logic I used before for filtering my goals. So goals.filter like this. Return that, comment it in and now Vue will automatically see which other refs or which other data you're using in this computed property and it will then recalculate this computed property whenever one of these reactive values changes. For example, here whenever goals changes, it will then recalculate the computed property. Now, we should store the computed property somewhere and I will name it filteredGoals because that's the name I used before in the Options API as well. Now we've got the filteredGoals and we do need those in the template. So now I will expose them in this object returned by setup and I will use filteredGoals as a key name and then point at the filteredGoals constant, which holds the value which should be exposed. And with that, we're exposing all the data this template needs. It also needs a method though. And how do we replace methods when using Composition API? Well, you simply define a function here in setup. This might look strange at first but you can absolutely add functions inside of functions. So you can define a function inside of setup and we're doing nothing else here with this anonymous function by the way. So we can add a function. Name it addGoal, for example. And in this function, do whatever you wanna do. Now again, I'll do the same as before. So I'll copy the logic I had in the method before. Add this here. And now with that added here, I just have to adjust one thing. It's no longer this.goals but just goals because I'm referring just to this goals constant, which is part of setup and therefore, available in this nested function as well. This will now change goals and because goals is a ref, Vue will be appear of that change. Since goals is a ref, it will know that this computed property needs to be recalculated when goals changed and therefore filteredGoals will update whenever goals changed. And filteredGoals is exposed to the template. That's why the template will also be updated when our goals change. That's how this will work. Now, in order to be able to use addGoal and reference it from inside our template as we're doing it here, we also need to expose it to the template though. Because by default, nothing is available in the template. We explicitly have to return what should be available there. So here I can expose addGoal under an addGoal key. And if I do that, I replaced data, computed and methods in this component with the Composition API equivalence. So if we save this now, I get an error. Must use value to read or write the value wrapped by a ref. This is important and I'm showing this on purpose because I mentioned before that ref creates a wrapper object and this is important to be aware of. When you then work with this ref, you're not working with the value you passed to the ref function, you are working with the ref wrapper object. And you get access to the wrapped value by accessing .value on the ref. And this has to be .value. This gives you access to the wrapped value and allows you to change this value or read from it. So we have to use .value for pushing a new goal and for filtering. Now, the other error is saying that text is not defined. And that simply is coming from this line here. Of course, addGoal previously received a text parameter. I should still add this here to this function. But now if we save this, and reload, this works. And I can learn Vue! But learning React written like this will not be shown. So this is the Composition API in action. And I also wanna highlight that in this app here, in this mini app, I'm using the Composition API in CourseGoals but not in AddGoal. There I still have the Options API. And not in GoalsList. So it's not a thing or it's not a feature you have to use in the entire app. You can migrate individual components to the Composition API and mix those components with other components that still use the Options API. You can even use the Options and the Composition APIs side by side in the same component, though the two sides will not really be able to interact with each other and typically, you will probably migrate an entire component. Now, regarding the not able to interact with each other point, in the setup method, you don't have access to this. You can't read any data you might have in the data option. You can't access anything with this in here. And this, of course, could be a problem if you are in a component that needs some props because normally, your props are available through the this keyword. Now, we don't need props here but if you would need access to props in setup, the good thing is setup receives a props argument. The first argument you get here is a props object, which holds all the props a component might be getting. This component gets no props, so we don't need it but if you would need it, this is your friend because using this is not possible in setup. Now, for all the other edge cases, like how you could use this.$router and so on, you best visit their official docs or you dive into other resources like my course, for example, because there I dive way deeper into the Composition API and I also cover how to use the router or Vuex with the Composition API. But the core logic hopefully is clear now. We can also practice it again on AddGoal. Here we also have data methods and now a watcher. We can replace all of that with the setup method and now in there, we've got data, two pieces of data and therefore again, here I will use refs. I will import ref from vue and then simply create a new ref with an empty string, which is my enteredText and also the invalidInput, which holds false initially. And then here, we can return enteredText and you can use a JavaScript shorthand here. If the value name and the key name is equal, you can omit the value and the colon and it's automatically expanded to the longer form behind the scenes. And invalidInput is also exposed like this. So now these two refs are exposed to the template. In the template we're using them, for example, for two-way binding but also for v-if. And one important note about refs and the template, in the template, you don't need to access .value to read or write. You don't need to do this here because in the template, Vue automatically drills into that value property for you. So in your JavaScript code, you need to use .value. In the template, you don't. A very simple rule. So now we've got the data, we also need the method, the addGoal method. So I'll just copy this here. And create it as a function like that. Now, here of course, we don't set this invalidInput to false but invalidInput.value. We don't check this.enteredText, but enteredText.value. And we update invalidInput.value again. We also set enteredText.value to an empty string down there. Now, what about emitting? How do we do this if we don't have access to the this keyword? I mentioned that setup receives a props object. It also receives a second parameter, a context object, which holds extra pieces of information or of functionality. And on this context object, you can call emit, however, not with a dollar sign but just like this. Context is an object with an emit method, which allows you to emit a custom event. And here, of course, we emit enteredText.value as a value. Now, I don't need props here so I'll rename this to an underscore so that we still take this argument but I signal that I'm not planning on using it. Otherwise this project setup would complain about an unused argument. But with that, we added this function and we can also expose that under its name to the template. Now, what about the watcher? Here, this watcher. We can also set up watchers with the Composition API. You can import watch from Vue for that and simply call watch in your setup method. Now, watch takes two arguments. The first argument is the dependency of the watcher. The second argument is the function that should be executed when that dependency changed. So here in this case, we have this logic here in the watcher. This if check where I want to log the invalidInput output. Like this. And this should be locked whenever invalidInput changed. So invalidInput is our dependency. Not .value but just the entire ref. For a watcher, if you provide a ref, Vue will automatically drill into the value property. And whenever this value changes, this function will now be executed. And here we also get access to the latest value. We also get access to the oldValue if we wanted it as a second argument. Now we then can run this code and we should print this to the console whenever this changed and is true. And that's it. If we now saved that all and reload here and open the console to see our log from the watcher, I can add learn Vue and this works. But if I click Add Goal like this, I get my error here and this watcher console.log every time I press this without a value. And then, of course, I can also enter a valid value again. So now we migrated this to the Composition API as well. Now, when it comes to App.vue and GoalsList, there's nothing we need to migrate here because we're not using data methods, computed or a watcher here. And when it comes to props or components, these options are not touched by the Composition API. If you use the Composition API instead of the Options API, it's really just mainly about data, methods, computed and watch. Lifecycle hooks are also used a bit differently but that's also not something I'll dive into here. You can check out the official docs or my course to learn all about that but with this video, you hopefully got a good introduction to the Composition API. And now to circle back to the beginning of the video that the Composition API can help us in bigger projects and bigger components, here's that example from the beginning again what you find in my course. There we had ProjectsList and UserList and I mentioned that with the Options API, the different kinds of logic were scattered out and reusing logic was difficult or cumbersome. Now, I migrated it to the Composition API and now the advantage could be that we know have all the search logic in one place. Actually here in a custom hook, in a custom composition function, which I created, which now contains the search data, the search computed property, the search watcher, the search function and exposes all that to the place where this custom hook, this custom function is used. For example, the UserList and I can simply call my custom function here to get access to all that data and so on, which is managed inside in that function. And I can still expose it in this setup method to the template of this component. And I can use the very same reusable hook or composable custom composition function, whatever you wanna call it in ProjectsList, for example. And that can be the benefit of the Composition API. It allows you to write elegant code like this, reuse logic and have all the logic and all the data that belongs together in one place. It's optional but in bigger projects, it could be useful.
Info
Channel: Academind
Views: 76,457
Rating: 4.926106 out of 5
Keywords: vue, vue3, vue.js 3, vuejs 3, vuejs3, vue 3 tutorial, composition api, vue composition api, vue 3 composition api, composition api tutorial, vue composition api tutorial, full course, vue 3 course, free course, maximilian schwarzmuller, maximilian schwarzmueller, maximilian schwarzmüller
Id: bwItFdPt-6M
Channel Id: undefined
Length: 23min 45sec (1425 seconds)
Published: Mon Sep 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.