Vue JS 3 Tutorial for Beginners #11 - The Composition API (part 2)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so then i'd like to now talk about how we can use props inside the setup function and with the composition api now to do that we're going to need another component so that we can nest that component inside the home one and then pass a prop into it so what i've done is stripped back all of the code we've been playing with for the last couple of lessons and i've replaced it with this right here we have the setup function and inside we have a ref called posts and that is an array of two objects each object is a single post has a title a body and an id so we have this and we're returning it right here and this is what we're going to pass in as a prop to another component now the first step is to create that other component and that will be called post list dot view inside the components folder so now we need to flesh this out a little bit so first of all we'll say view to create this boiler plate and then i'm going to say div dots post list like so and inside here is where i want to cycle through some posts now we need to pass those posts in as a prop and we need to nest the post list component right here so let's do that i'm going to say post list first of all and then down here we need to import the post list so let's do that i'm going to say import post list and that is from and then it's dot dot forward slash to come out of the views into components and then we want the post list dot view now we need to register that as well so components and it's just the post list like so and then a comma okay so now we can pass this post's value into the post list as a prop so we'll data bind we'll call the prop posts and set it equal to posts that's all we need to do we're just passing it in as a prop same as normal okay then so inside the post list we can now accept it but how do we accept it well we still need to say props down here inside the component object and that will be an array and we want the posts so that's the first step now we can use the posts just as normal now inside the template so nothing's really changed at the minute the only thing changing is how we're creating the posts and returning them so we can use them over here so now i have them i can do something with them so what i'm going to do is cycle through them so i'll say div and then we're going to have a v hyphen 4 and set that equal to post in posts now we also need a key on this for each item so data bind to a key and then set it equal to post dot id remember we have the id property on each post so then inside here we could do an h3 and output the post title so we'll say post dot title like so all right so if i do this then come over here then we can see those post titles so this is working as it should do now what if i want to use this inside the setup function well i would have to say set up and then we can take in as a first argument to this props and then we could access them inside the setup function so i could say console.log props like so i'm going to save this and then i'm going to refresh and we can see now this is a proxy object and inside that we have if we open these objects the posts property now if we want to access them directly we can say props dot posts like so save that and now we can see if we scroll down we get this object which is just the posts right here don't worry too much about what this proxy means this is just like a wrapper wrapping around the object but if we want to work with them inside the setup we can just say props dot posts now then i'd also like to create a further component and that will be called single post so let me do this i'm going to say single post dot view and inside this i'll boiler plate our components and this is going to be for a single post so what we'll do is instead of the h3 here we'll nest a single post and we'll pass in as a prop the post so i'm going to say post is equal to post like so and that's all we need to do oops let me just format this correctly like so that's all we need to do now we have access to the post because we're cycling through the posts right here and we're passing it in now as a prop to single post now in order to use this we need to import it so let's do that import single post from and it's dot forward slash because we're in the same folder single post dot view and then down here we'll say components and it's just the single post like so okay so now i can accept a prop inside this component and i'll do that here i'll say props and then post now we can do something with this so what i'll do is come to the template and create div with the class of post and inside that i'm going to output the post title so i'll do an h3 for that and say post dot title so this should still work if i come over here and refresh we can see the titles are still there now this time around i also want to output a post snippet so imagine we had a lot of content for the body right here i don't want to output the whole body i just want to output a snippet of the body maybe the first 100 characters or something like that so the first thing i'm going to do is replace all of this with a load of lorem ipsum and save it now if i was just to output the boast body let me do this p and then post dot body like so then it's going to output the whole body like this i might just want to output like this much or even just this much or something like that as a snippet for the home page and then when we see the blog details later then we'd show it all so how do we create this snippet well i'm going to come inside the setup function and i'm going to accept the props and in those props we have the post so i'm going to say const snippet is now equal to a computed property press enter make sure it imports that right here and inside this computed we're going to fire a function and it's going to return a snippet based on the post that we have on the props so return and then props dot post and then dot body and that's the property that we want to kind of make a snippet from remember if we take a look over here this property is the body and to make a snippet we're going to use a string method called substring now this takes in two arguments where do we want to start and where do we want to end so we start at the zero position the start of the string and we'll go up to 100 characters and this returns to us the first 100 characters of the string we're gonna tack onto that as well three dots at the end or four dots just so we know there's more to this so now if we use this snippet in our template it's going to get us the first 100 characters and these few dots at the end as well but first of all we need to return it so we can use it in the template return the snippet like so and then we can output the snippet right here so save that and preview and now we just see a snippet right here which is better so hopefully you can see how we can use props a lot of it is the same way we just pass in props as normal like this but if we want to use them inside the setup we have to take them in as the first argument and then we can use the different properties on the props earlier on in the course we saw that we could use lifecycle hooks inside component objects something like this we could say mounted to run some code when the component mounted or updated to run some code when the component updated for example if our data changed and it had to reflect that change in the template now we can still do that when we're using the setup function as well there's nothing wrong with doing that but we can also use lifecycle hooks inside the setup function now the way we do this is just by importing whatever hooks we want from view and there is a slight change in the name of the hooks as well the only change is it's on before each of the hooks so instead of mounted it would be unmounted instead of updated it would be on updated so i'm inside the post list and i'm going to get rid of this console log right here we don't need that anymore and i'm going to use the on mounted hook click on this and it should import it for you from view so all we do is pass a function into this and this will fire some code when the component is mounted now all i want to do is log something to the console so console.log and i will say component mounted now we can do other hooks as well so we could say on unmounted for example and it should import that up here and we do the same thing passing a function which will run when this component unmounts so again i'll just say console.log and i will say component unmounted and finally i'll do one more i'll say on updated press enter it imports that hook for us and again we're passing a function this time i'll say console dot log component updated so this will happen whenever any kind of data change happens which will force a re-render so in our case maybe if the posts change that we pass into this component because if they change then this stuff right here is going to change we'll be passing different posts in so what i'm going to do now is just save this and open up the console over here and i'm going to just get rid of that i'm going to refresh and we can see component mounted now we don't see the others because there's no updates and we're not on mounting the component so what i'm going to do is go to the home component and i'm going to implement a little bit of functionality whereby we can hide and show the posts in which case this component is going to unmount if we hide it and also where we can change the posts in which case we're going to run the on updated hook so the first thing i'll do is create a button right here and inside that i'll say toggle posts so i want to be able to hide and show this based on a user clicking this so i'm going to create a property inside setup and this will be a reactive property so const show posts is equal to ref and we want this to be true to begin with so they do show and we also need to return it down here like so and what i'll do is only show this if this is true so i'll say over here v if is equal to show posts so if this is true then this will show the minute it turns false then this component is going to unmount it won't show anymore and at that point it will run this function so let's toggle that using this button i'm going to say at click is equal to and we'll say show posts is equal to the reverse of whatever show posts currently is so if it's currently true it will turn it to false and vice versa so let's save that and give this a whirl and i'm going to get rid of all this right here so if i refresh we can see component mounted if i click on this it should hide this and we can see component unmounted toggle again component mounted toggle again component unmounted all right so we can see that that life cycle hook right here is working and it's firing whenever the component unmounts so let's now try and fire this one by changing the posts data to do this i'm going to create another button and inside the button i'll say delete a post and all we'll do now is attach a click event to this whereby we take the posts and we use the pop method on it and that just basically removes one from the posts array we have access to this because we have the posts returned to us and we can change it directly in the template by using this pop method so that takes one of the posts therefore the data right here changes going into this and since this data changes we'll be outputting a different number of single posts therefore this template is changing and when that happens when we're updating a component this will fire so let me save this and come over here and i'm going to delete a post and we can see we get rid of one of those and it says component updated and the rest still works unmounted and mounted so there we go that's how we use these different lifecycle hooks inside the setup method using the hooks and they're all called on whatever the hook was called beforehand and again we don't have to place them here if you want to you can place them down here so i could say mounted and then run some code in here so i'll say console.log and we'll say mounted using options api like so if i come over here and we can see mounted using options api so that runs as well so you don't have to use them up here but i generally will when we're using lifecycle hooks from now on all right then so in this chapter we're going to move on to performing asynchronous code inside the setup function down here so we have used asynchronous code before when we fetch data from the db.json file using json server we're going to do a similar thing now but this time it's all going to be from within the setup function now in this chapter we're going to be using async and awaits which is a way in javascript that we can handle asynchronous code and promises so if you don't know what that is i would highly recommend that you first of all check out one of the last videos in the last chapter of this course where i talk about the basics of async and a weight get up to speed with that first of all and then come back so that this is not confusing okay if you know about async away then feel free just to carry on anyway what i'm going to do is i'm going to create a new data folder over here because we're going to create a db.json file again db.json and we'll store all of our data in here again later on we will be using a database but for now i just want to store in db.json and i'm going to paste this data in from my repo and it's just one resource we have posts that's an array and there's two objects inside it so two posts each one has an id it has a title it has a body and also some tags which is an array of different strings different tags okay so each one of these represents a blog that's the data that we're going to be working with the next thing i want to do is install the json server package so let's open this up and install it for this project we'll say npm install json hyphen server and press enter and now that's installed i'm going to use json server to watch our db file so go into the data folder and then we want the db.json file press enter and now we have access to this endpoint for the posts cool okay so next what i'd like to do is delete all of the data that we create inside the setup function because now we're going to try and get the data from the db file instead so i'm going to delete these two objects inside the array but i'm going to keep the array as the initial value for posts we're going to keep this ref to store our posts in once we've fetched them so to begin with it's an empty array after we fetch them we populate that array now i also want to make another ref and that is going to be called error just in case there's an error with the request now it's going to be null to begin with but if there is an error later on we'll populate this value as well all right so now let's try and fetch the data now like i said we're going to be using async and a weight to do this so first of all i'm going to create an async function and i'm going to call that load so we set it equal to an async function like so and that means that now because we've denoted this as async we can use the awake keyword inside this now i want to place my logic inside a try catch block like this and the way a try catch block works is that we try to do something in our case we're going to try to fetch the data and if it works great it doesn't use this catch block if it doesn't work and there's an error this catch block will catch the error and we can do something with it that's how try catch works and this is generally the approach that we're going to take when we're working with async and a weight so then let's now get the data i'm going to create a variable called data and set it equal to a weight and we want to use the fetch api to do this so what this does is perform the fetch and instead of going down to the next line of code down here it will wait until that fetch is complete right here because we've said await it once it's complete the response will be stored inside this data variable all right so we need to put an end point into this and remember that end point is right here so we want to get all the posts so i'm going to copy that and paste it inside a string in there so we're awaiting this and now we can do something with the data once we have it all i'm going to do for now is log out the data so console.log the data like so save that and i'm going to come over here we don't see the post anymore because we deleted the local data i'm going to open up the console and i'm going to refresh in fact this won't work because we're not calling the load function anywhere so now let's call it down here so that it runs this code okay save that and now come over here and we can see we have this response object now you see this thing right here this okay means the response was okay and we have data back so i want to check that it is okay before i try to do something with the data now remember when we use the fetch api we have to use the json method to pass that data but first i will make sure that the response is okay and if it's not then we're going to throw an error whereby we can catch the error right here if it is okay then we'll pass the json and we'll use that data okay so let me delete this and do the if check i'm going to say if data dot okay and then open this up now this is if the data is okay but i only want to run this bit of code that i'm going to create here if the data is not okay so all i need to do is place an exclamation mark right here so now if it is okay then this whole statement will be false and it won't run this if it's not okay the whole statement will be true and it will run this and that's the scenario that i do want to run it when the data is not okay because now i can throw an error so i will throw the error and i'll say no data available you might create better errors in your applications and we'll probably do that later in our other project but for now this will do so when we throw an error right here inside the try block this catch block will catch that error and this error will now be this area that we've created right here and we can do something with that error so i could update this right here with this string so to do that i'm going to say error dot value which is this right here remember we use the value property to update it and set it equal to the error object that we have right here and the message property which will be whatever message we've created right here so now we're updating this with this message okay now i'm also going to log it to the console so we can see it console.log and we'll say error dot message all right then in fact we'll output instead error dot value just to make sure that this thing has worked right here okay so if i save this and refresh at the minute then we don't get that error but if i was to come over here and just change this to post instead which doesn't exist then we see no data available so we're catching that error and we can do something with it and later on we could output it in the template but for now we won't bother with that okay so let's change that back to posts now this is the case if the data is not okay if there was an error like we had a minute ago if it is okay then it bypasses this if check right here and down here what i'm going to do is just update this post right here but first of all we need to pass the json data into javascript so let me come down here and say posts dot value is equal to awaits and then data dot json so we take the data response we have and we use the json method on it this is asynchronous remember it returns a promise so we use a wait in front of that to wait here until this is done once it's done the value will be passed into this so now we're updating the posts and since we're updating that now we should be able to output them to the screen so let me save this and preview and we can see now they're on the screen awesome now there's a couple of things i want to do in the template first of all i want to output the error if there is one so i need to return the error at the bottom of the setup function this thing right here because we want to use it and i'm going to check if there is an error if there is will output it so i'll do a div tag first of all and we'll attach v if to that like so and we want to check if there is an error now if there's not it's going to be null so it won't output anything if we assign a value to it like we do here then it will output the error in which case we'll just say error like so okay so if i save this and come over here and refresh we don't see the error because there's no error but if i change this to post and save it then we can see right here no data available all right cool so i want to also output down here a loading message if this is still being loaded so basically we only want to try and output this if we have a length inside the array if we don't have a length inside the array then we can say something like loading all right so let's now do another div tag and then attach v if to that and say if posts dot length now if this is the case it means that the post value has been added to and we have a length to it in that case i want to output the posts and now i can add another div down here and i can say v else and output instead loading dot dot dot so what we're doing is checking if we have length to the posts if we do have length then obviously this load has done and we can output the posts if we don't have length then this vls will fire and it will say loading and we won't have length until this is complete so save this and come over here and now we can see no data available that's because of this thing right here so let's save that and if we refresh you'll be able to see loading very very quickly if you look very hard refresh again and basically we can just see a flash but i promise you it is there it says loading for a split second then when we have to post it shows the posts so this is the basics of how we can work with asynchronous code inside the setup function all right then so we've seen how we can use asynchronous code to fetch some data inside this setup function right here and that's good it all works however imagine this scenario you had a very big application with loads of different components and on different pages and different sections of the application you might want to use this same data now in that case you'd have to essentially repeat all of this code in any component that needs it and that's not very efficient you don't want to be repeating your code over and over in different places so one of the benefits of using the composition api in the setup function is that we could externalize all of this logic into a separate function in its own file and then we could just import that function in any component that needs the data and invoke the function inside the setup hook for that component so then we're only defining all of the logic once in one file and importing and using it wherever we needed it so that's what we're going to do now when we create these external functions we tend to call them in view either composables or composition functions but you don't have to call them that it's not the official name i don't think it's just what i call them and it's what i've heard other people call them as well so that's what we're going to do we're going to make a composition function or a composable to house all of this logic and then we're just going to import it into this file so we can use it so what i'll do is create a new folder inside source called composables and this is the way i'm going to create composables in the future i'll always create a folder called composables to put those files in and each composable will generally have its own file so i'm going to create one here called get posts since that's what it's going to do and this is a javascript file not a view file we're not making a view template or anything like that we're just creating a javascript function so let's create that function i'm going to call it get posts and this is also generally what i do i name the function the same as the file i'm going to set that equal to a function and inside this function we want to put all of this logic right here so i'm going to cut all of that and then i'm going to paste it inside this function now let me just scoot this up over here and one thing i'm not going to do is invoke the load function right here i don't want to do that inside this function i only want to do that from the component that uses it so i remove that but now what i need to do is return some things from this function because if i invoke this function over here yeah okay it's going to define these and it's going to define this function but that's all it's doing we can't then access any of these things from inside this component so i need to return some values so that when we invoke this function it returns those values and we can capture them so i'm going to at the bottom return an object and it's going to have the posts inside the object which is this thing right here it's also going to return the error if there is one and also the load function we need that to load the data this automatically doesn't run when we invoke this we have to return the load function so that we can capture it when we invoke the get posts method or get post function and then invoke the load method right here so that's what i'm doing i'm returning these things now also we have to import inside this file ref because at the minute it's not going to know what ref is we imported it into this file up here but we're not using it inside this file anymore we're using it inside get posts so i'm going to cut it from here and i'm going to paste it at the top of get posts over here and now we can use it and then finally i want to export this get post function from this file so that we can import it in other files so i'm going to say export default get posts okay so now we're exporting that we can import it inside this function i'm going to do that at the top i'm going to say import and we want get posts from and it's going to be dot dots come out with the current folder forward slash then into composables then we won't get posts and we don't need the dot js here it automatically knows that this is a javascript file okay so now we can invoke this function inside setup so i can say get posts like so and that's going to run this function right but what does that do well it creates these values it creates this function but it doesn't run the function and then it returns these values so we can grab them from this because this returns those values so i can say now const and then do some destructuring to get values from this and all we need to do is place inside this object any of these values that we need so i could get the posts from there the error from there and also the load function from there and now i can use any of these inside this component so i want to use the load function to invoke that load method that will actually run this function it will get the data it will update the error if there is one right here and it will also update the posts once we get them and don't forget we're returning those and we're grabbing those here so now we can use them inside this function so initially when we invoke this function post is going to be an empty array and this will be null but after we use the load function then after a second or so this right here will have a value or this will have a value if there's an error does that make sense and we're still doing the same thing down here we're returning these values posts and error so all of this is still valid up here as well we can still use post and error so this is a much better way to organize all of our logic we're just externalizing it inside a separate function which we're going to call composables or composition functions and then we're just using that function in any component that needs it we import it and then we grab what we need from it and then we can use it all right so let's save this and refresh and hopefully everything still works we saw loading for a second and then these appear like this now if i go over here and change this we should see an error come over here and we see no data available all right so this is all working and we're going to be creating several different composables or composition functions throughout the rest of this course so don't worry you will get more practice at this now there is actually one more thing i want to do in this video and that is to go to our single post components and also output the tags because remember if we take a look at the data we have this tags array as well and now we're fetching this data we can access those tags and output them so let me go to the single post component again and we have the post title we have the snippet and now i'm going to cycle through the tags so i'm going to say span first of all and then attach a v4 to this so we can cycle through them and that is going to be for tag in and it's post dot tags so we have the post available to us and we're just accessing the tags property on that post we're cycling through them and referring to each one as a tag so now we can output them but before we do that we need a key so let's bind to that and set it equal to tag and we're going to make it so that tags are unique so a post can't have the same tag twice so this key will be unique okay so inside that i'm just going to output a hash symbol because a lot of tags have that before them and then output the tag itself so if i save this now we should see all the tags for each post as well okay then so now what i'd like to do is create a details view a details component so that if we click on one of these posts right here then it goes to the details for that post and instead of just showing a snippet we show all of the content for the post so to do this we're going to have to set up a details component a route for that details component and then we're also going to have to fetch that single post now we're going to create another composable function to make that fetch to create a single post we have a composable for getting all of the posts but we'll make one for a single one too so the first thing we need to do is create the details component inside the views folder so details.view i'm going to boilerplate this and inside the template i'm just going to say details just so we know that we've landed on this page if we view it now the next thing i want to do is go to the router file and create a route for this component so another object the path is going to be forward slash posts forward slash and then a route parameter called id so that will be the id of the post that we want to view now the name of this route will be details and then we also need a component for this oops component and that will be the details one so we need to import this at the top so i'll duplicate this and change home to details like so now i'm also going to say right here props is true so that if we link to this page we can access the wrap parameter as a prop inside the details component so now we do need to link to this page and we're going to do that from the single post this is where we output a single post right here we're going to place a router link around the h3 so let me create this router link like so and then i'm going to close this off open it up and i'm going to paste this h3 inside the router link okay so where do we want this to go we'll say 2 and set it equal to an object and we've put a colon right here so we can use the object with data binding and the object will have a name property which will be details that's the component we're going to but also we need the params property because we're sending in a wrap parameter and the route parameter we need is the id and that will be the post dot id remember we have that inside the data the id property on each post so we have the post right here we have access to that inside the template and so we can just say post dot id so now if i was to click on one of these things over here it will go to post forward slash the id of that post so let me refresh again come over here and now we can see post forward slash two all right then so the next thing we want to do inside this details component is actually fetch the data based on the id now we need to accept as a prop first of all the id so we can use it so we'll say props and then inside here id we also need a setup function whereby we can take in the props object so we can access the id inside here as well so the next step now is to create that composable function to fetch a single blog post using this id so then let's create inside the composables folder a new file called get post dot js to do this so this time get post not posts all right so the first thing we need to do is import the ref value from view so i'm going to say import and then ref from view because we're going to use refs inside this function now let's create function and we'll call it get post and set it equal to a function all right so inside what i'm going to do is actually just copy a lot of this code right here from our get post function because it's going to be quite similar and i'm going to paste it in so this time around we're going to have a reference called post not posts and it's not going to be an empty array because we're only getting one post instead i'll set it to be null to begin with the error is also going to be null to begin with now we also want a load function which is asynchronous and we try to get the data only this time it's going to be a different endpoint remember to get a single post it's forward slash posts forward slash the id now we don't have the id inside this function yet so when i call this function from inside our details component i'm going to have to pass that id in as an argument and then i will accept it inside this function so now i could just come over here and say tack on the id to the end and then this is our end point so we're going to fetch that we're still going to check if we get an okay response if we don't then we throw an error and we'll say something else in here like that post does not exist so if there's a problem getting the post we'll just throw this error and then down here we catch the error and we update the error value and then if the data is okay we bypass this we want to update the post value this time not posts so we change that to post.value and again we pass it into a javascript object this is asynchronous so we await it and the value is updated after it's done okay and then at the end we want to return post not posts the error message if there is one and the load function so that is pretty much done now now this is getting a single post not a bunch of posts and at the end we return that post right here now i need to export this function so export default and then the function name which is get post and now all we need to do is use this composable inside the details component so that's pretty simple to do all we need to do is first of all import the composable so import get post from and we want to come out of the views folder so dot dot forward slash into composables and then we want the get post function so now we can use it inside this setup function i'm going to say get post like so now remember inside this function we take in the id we need that so we need to pass it in right here as well and we can do that by using the props dot id so now since this returns a few values we can say const and then destructure whatever values we need and we want the single post we want the error if there is one and also the load function cool so now we can invoke the load function to start this fetch it's going to try and get the data and then we're either going to get back a post or an error now we need to return both of those values so we can use them inside the template post and error like so so now we have those we can go and flesh out this template now i want to check if there's an error first of all so i'll make a div and attach a v if to that which is equal to error remember that's not to begin with but if there is an error it gets a value and then this will show and in this case we just output the error like so now i want to do the same thing but this time check for the post so another div and then i'm going to say v hyphen if and set that equal to post so if we have a value for the post now then we're going to output this i'm also going to give this a class so we can style it later on and that class is going to be post all right so inside this i can output the title inside an h3 so let's do that first of all close off this h3 and then output the title inside that so post.title and then below that we can also output the body so i'm going to do this inside a paragraph tag and i'll also give this a class equal to pre so we can style this as well and i'm going to output right here the post dot body like so okay so outputting the title and the body now so let's just save this and take a look if i click on one of these and refresh this page we can see now we get the title and the body if i go back and click on another we get the title and the body awesome so this is working and it all looks good we've created our second composable function now and this could be reused in any component which needs to get a single post now finally i just want to add a few styles to style up this and this so i'm going to paste these in at the bottom and all i'm doing is applying these styles to the post which is this thing so a max width of 1200 pixels margin 0 and auto post p so that's this thing right here i've said the color is this the line height is 1.5 margin top 40 pixels and anything with a class of 3 we're seeing white space pre-wrap so it goes on to the next line so i'm going to refresh over here and get those styles it looks pretty much the same so far but as we go further into the blog we will style it a bit better as well
Info
Channel: The Net Ninja
Views: 36,943
Rating: undefined out of 5
Keywords: Vue, vue 3, vue tutorial, vue 3 tutorial, vue js, vue.js, vue js tutorial, vue.js tutorial, vue js tutorial for beginners, beginners, tutorial, vue.js 3, vue 3 new features, vue js 3 tutorial, vue.js 3 tutorial, vue 2 vs vue 3, compostion api, vue 3 composition api, vue composition, vue composition api, composition api tutorial, composition functions, vue hooks, composables, vue composables
Id: 0FwBjPeLqQ8
Channel Id: undefined
Length: 43min 1sec (2581 seconds)
Published: Wed Dec 16 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.