In this Vue.js tutorial, we are gonna take a deep dive and look at the lifecycle hooks provided from the Vue framework.
Now, we’re going to analyze the lifecycle diagram, and then go and implement this into a Vue application. We’re also going to extend it, because this lifecycle set of hooks and what they list in the documentation is helpful for understanding, because it’s a helpful visual. But I think that it’s missing a couple of elements that I personally have had to implement into my own production Vue applications, and so I think it will help for you to see those as well. So we’re gonna walk through quite a bit of material in this guide.
So I have a Vue application running right here in the background, and we’re going to be looking primarily just at a few different components. So we’re going to be looking at a dashboard component, a Vue component right here, and then that has the nested login component.
And so what we’re gonna be doing isn’t as much building in this guide, we’re instead gonna be looking and analyzing to see how exactly the lifecycle process works.
If you are not aware of this, if you’ve never heard of the lifecycle, or if you’re just trying to understand it for the first time, the best analogy that helped me is trying to compare a Vue component to us humans.
So as a human, we are born, we go through different stages in life, and then, even though it may seem dark, we all die at some point. Well, that’s the way a Vue component works too. A Vue component is born. We say that a Vue component is created, then it has a number of things happen. It has changes go on, such as data changes, and updates, and those kinds of. And then at a certain time, it also dies, or we say that it is destroyed.
So what we can do with Vue is we can actually listen for and capture those events, each one of those, from created all the way through destroyed, and then update the application based on the state of the component.
So hopefully that starts to make sense. But what really help understand the lifecycle hooks and the entire process was really just getting in and implementing each one of the methods.
I’ll provide in the show notes a link to this documentation, ’cause that can help to have a visual. But I think what helps the most is just going in and writing the code.
So I’m going to switch back to our application here, and then opening up Visual Studio code here, you can see that we have our homepage component, which is just rendering out some content, and then our login component. And that’s pretty much it. That’s pretty basic right now.
So we’re gonna start in the dashboard, and I’m gonna go out, and I’m gonna start listing some of these hooks. Now, right now we have a pretty basic setup where we have our data function, then we have a list of the components that we are registering, and then we have one custom method. I usually by convention place these lifecycle hooks right above the methods, I like to have my methods at the very bottom, so I know exactly where they’re at. But you could technically put these anywhere inside of the script tag, as long as it’s right after the default curly braces.
Now, I’m going to just list off a couple basic ones here first. So I’m gonna say beforeCreate(), and it is a regular method, so you have to have the parens right after it. And then I’m going to console.log and then say beforeCreate, just so we know exactly what’s happening here. And then for this one, I’m also gonna say this afterwards, ’cause this can be really helpful in understanding what we’re referencing. And then make sure you put a comma there. And then after that say created.
Now, unlike some other methods or names inside of Vue, these are reserved words. So before create is something provided by Vue directly. Created is something provided by Vue. So these are reserved and they are names and functions that are built directly into the Vue source code.
I’m going to copy this console log here, and then change this to say created. And I’m not gonna pass in this or else it’ll make the output a little bit messy, and you’ll notice that the this that it’s referencing is gonna be the same for all these elements.
So let’s just start with these two, and then we’ll get into some of the other ones after this. So switching back to the browser, I’m going to clear the output, hit refresh, and now you can see that we have some console log statements here. We have before create, and then created. So both of these worked. So they were triggered. Notice that we didn’t do anything. All we did was we listed them out inside of the component.
Now, when I used the this call, so when I said beforeCreate and then passed in this, all this is doing is giving a reference to this component, meaning the dashboard component. And the way we can know that is this is an object. And so if I click on here, I can see everything inside of it, everything that has reference too. So you can see it has a list of attributes. So if I click on attributes, you can see it’s an object, and then inside of here all kinds of different object values.
Then this one is the one I think is pretty neat and very helpful is children. You can that our dashboard component does have two children. You can even just go and reference them here. We have a homepage content component, and then a login component. And that is what this is referencing here. And then it has a element so that we know that it’s a diversity. You can hover over it, and you can see what the element entails, it can have listeners, you can have a list and a reference to its parent.
So that is kind of a helpful way of understanding what this is. I want this guide to specifically focus on the lifecycle components, but I just put that in there just so you can see that you have a reference, you have a direct reference to this inside of each one of these lifecycle hooks.
So you saw that these were already triggered. Let’s move down. I’m also gonna get rid of this and clear it out, just so we have some nice clean output.
Now I’m gonna go and I’m gonna list all the rest of the lifecycle methods that we have access to. So the next one’s gonna be mounted. And then the one after mounted … or actually, you know what, I forgot one. There is one right before it called beforeMount. And so we have access to beforeMount here, then mounted.
And then from there we have our update methods. So this one is going to be beforeUpdate. And there’s gonna be something a little bit tricky with the update method that I’m gonna show you here in a second. Then the next one is updated.
So we have updated, and then we just have two more. So we’re going to have our beforeDestroy, and then we’re gonna have after that one our destroy, beforeDestroy, and then destroyed.
I do like the naming that they went with here. If anyone has ever been through my tutorial for the React lifecycle hooks, React went with a little bit more challenging of a naming process, and it makes it a little bit harder to remember all of them. But Vue, I really like the names that they went with, because you can pretty much, as long as you can remember half of them, that means you have remembered all of them. You have beforeCreate, created, beforeMounted, mounted, beforeUpdate, updated, beforeDestroy, and then destroy. That’s a very kind of a common approach to being able to name them. So you just have to memorize about four items, and then you’ll know all of them.
So now that we have that, let’s go and switch back to the browser here. And I’m going to refresh, and let’s see when each one of these is triggered. So right now, we have beforeCreate, created, beforeMount, and mounted. So we before we did anything, notice we didn’t do anything on this page, nothing happened, all we did was we hit refresh, then the page loaded, and four items here were triggered.
Now, let’s take a look at that lifecycle visual once again, ’cause it helps to kinda see all of the items that took place during that process. It may not seem like anything happened, but as you can tell, a lot of things were happening in the background.
So when the lifecycle diagram says new Vue, this means that a new component is being instantiated. So it’s going to run the intializer, which means it’s gonna be … intializer, it’s gonna be created, and then it’s gonna set up all of its data, and all of its dependencies, everything like that is being brought in, before create and created are gonna manage those processes. So if you need access to something very early on in the component lifecycle, then these are gonna be the lifecycle hooks that you would use.
Then the created method then is going to take it from there. It’s going to take it, it’s going to see, does it have an element option. If no, then it’s going to perform one process, if yes, then it’s gonna see does it have a template option.
So these items are really related directly to the data that’s being rendered out onto the screen. It’s checking to see what kind of values that it’s gonna be presenting, if it is gonna presenting them to the user.
Moving down, you can see from there it’s gonna check to see does it compile the template into a render function. If yes, it’s gonna come this, or if it has a template option, then it’s going to then say compile the elements outer HTML as a template.
Now, if some of this is confusing, don’t worry. It’s very confusing especially if you’re new to Vue. I more just wanna kinda show you that as you are building your Vue applications out, you’re gonna noticing a lot of things are happening behind the scenes. And sometimes that can be a little bit confusing or intimidating. I wanna show you that there’s actually just a set of processes that Vue is going through. It’s almost like a set of checkboxes, and it’s saying, “Okay, I need to know what this component is trying to do. Is it trying to show the user something? Is it just a small presentation component, or does it have all kinds of data? And do I need to run all these processes?” So that’s really what this lifecycle is about. It’s Vue trying to figure out what it needs to do.
And then from that process, it goes into the beforeMount process, and then it creates the element, and it does all kinds of different Vue-related items, and then comes down into mounted.
Now, one thing I will tell you from experience. I built out multiple production applications in Vue, and I will tell you that I probably spend when it comes to these lifecycle hooks, I probably spend about 90% of my time using just two or three of them. And so I’m really gonna focus on those, and I’ll let you know which ones they are.
The mounted hook is most likely the one I use the very most, because this means that Vue is already figured out what kinda component it’s dealing with, it has initialized all of the different elements that it needs from a template perspective from the div element, it’s set up its own version of the DOM on the page, everything like that, and it’s mounted.
So this is where I do a lot of the set up for my components is in this hook right here. Now, once it is mounted, that means that it is loaded up on the screen. You can see if you come back here that mounted was the very final step in the process when the page loaded. And then from there, once it is loaded, now we get into what happens when something gets updated on the screen. Remember, one of the top reasons why you use frameworks like Vue, or Angular, or React is because you want your application to be dynamic. You want the ability for a user to click buttons, and type into forms, and to have other actions, and other behavior to be automatically triggered inside of that application. And so what goes on at this stage of the process is very critical. And you may have noticed that our beforeUpdate and our update did not get triggered.
Now, I wanna show you something a little bit interesting. This may be a little bit odd to you, but you know that we have a login form right here. And just to review what that looks like, we are calling a login component, so recalling an external component, and then we have this update listener inside of the login component. Well, you would think that would mean that when the data gets updated in login, it’s going to update our dashboard. But let’s see exactly what happens.
So if I type an email in here and click on login, you can see that it did console-log some data out, that is all that’s happening inside of this update login details. We’re omitting an update event, and we’re passing in the email. And that’s all we’re doing. But notice that our beforeUpdate and our updated lifecycle hooks were not triggered. And that is because we didn’t actually update anything inside of our dashboard component. Everything was encapsulated inside of the login.
Now, if I were to take these, so I’m gonna copy these functions here, and I’ll place me inside of the login component. Now, if I do this, and let’s just be clear here that we’ll say beforeUpdate from login, and then updated from login. If I hit save now and come back here and start typing, even as I’m typing, before I even submit the form, it is updating. We have the beforeUpdate and we have the updated, and both are only in the login, we’re still not making any changes directly in the component.
So this is something that can be very confusing, if you’ve never seen it before, because you may think that a parent’s components if it has any child component updates, you would think that it receives all of those. But Vue is very good at isolating those update events. So if you wanna capture something in the update stage, you need to make sure that you are doing that in the component itself.
So let’s stretch that, just so you believe. Let’s go into the dashboard, and I’m going to add one more little form element here. So I’m gonna say input text and we’ll connect this. So I’ll say bind it directly to the dashboard data model. So say v-model and we’ll just say something like maybe subdomain. It could be anything. It could be ASDF or ASTF, it doesn’t matter you can call this whatever you want. And then add in a subdomain data element here, so we have something that it can bind to, hit save. And now you can see we have this new form field. I’m gonna close this, and if I start typing anything, you can see that now that beforeUpdate and the updated lifecycle hooks were triggered. So that is one of the biggest take aways I want you to have from this entire guide, is understanding the way the update cycle works, because that’s something that you’re going to wanna tap into as you’re building out the applications, and understanding that it’s encapsulated inside of the component that’s being updated is very critical.So that is how the how the update process works.
And now we have two more, and I’m going to describe what they do, and then I’m gonna explain what their role should be, and then I’m gonna show you two more that weren’t listed. And these other two are ones that aren’t technically lifecycle hooks, but I think they should be seen in the same light, because they are used with the same type of intention, and hopefully that’ll make sense when I walk through it.
So what beforeDestroy and destroyed do is they are watching for when the component is removed, when it’s taken off of the stake. So let’s say that we have all of our data here, and then a user goes and clicks on home. Now, they’re redirected to the home component, and what happens, you can see right here, is our dashboard component has been destroyed, and it is no longer there. So the main role of what it is going on here with this lifecycle hook is that this gives you the ability to be able to clear off any processes.
So a very common thing that I use this for is say that you have an application and one of the component so has a timer in it. So I built a invoicing application that had a timer on one of the pages where you could record your time as you’re working. And that timer was running anytime that component was alive. Well, when the user left that page, the timer needed to stop or else the timer would keep on running in the background. So the destroyed hook allowed me to do that. I was able to say, “Okay, we are going to destroy that timer. We’re going to stop it from running that way we don’t have any memory leaks.” That’s really what the destroyed hooks are for, is for being able to clear out any processes the you do not want to keep running.
So let’s go back to the dashboard, and we’re gonna go through two more methods. And these are not listed inside of these lifecycle hooks, because technically they are route watchers. And when … I mean route watcher, I mean they’re watching for changes in the route by the user which that is technically not associated with the lifecycle hook, but it is associated with the way a user’s interacting with the component, and that’s the reason why I wanted to include it in this deep dive.
So now what I’m going to do is I am going to come down here under destroyed, and I’m gonna add a new hook. So this is gonna say beforeRouteEnter, and then this takes three arguments, to, from, and next. Now, inside of here … So what this is doing, and then also make sure you’re giving a comma here at the very end.
So what beforeRouteEnter does is it listens for when a user is trying to access this route. So the most common time that you’re gonna use this is to check to see … So say that you have a part of your application that you only want a authorized user to access. That’s a very common use case. Well, this allows you to do that.
So let’s say that we are connected to an authorization API, and I say const loggedIn, and for right now we’re just gonna assume they logged in successfully, the API said, “Yes, this user is authorized so we’re gonna say it’s true.”
But if they’re not logged in, then we want another process to take place. So here I can say next, and then as a string, pass in the path I want them to go to, which in this case means I want them to be redirected to the homepage. So this should give us the identical behavior we have right now, because we’re just hard-cording true in, and then it will change it to false and see if it works.
So I’m gonna come right here, and I’m gonna try to come to the dashboard. If I hit return, everything works, because it’s returning true. Now what happens though if this is false? So I’m gonna hit save, and now if I try to access the dashboard, if I hit return here, you can see it automatically redirected me to the homepage. So hopefully you can kinda see why I wanted to include these types of processes in a guide like this, because this isn’t part of the component lifecycle, but it is a part of the lifecycle of the user accessing a component. And so I thought that this would be something important, I thought it was missed out from a lot of the other tutorials I’ve seen.
So I’m going to now make this true again, so we can access the dashboard. And we can verify that by going to dashboard. And we just have one more function that I wanna go through.
So this next one is imagine they have a scenario where you have a user typing in a form, and they accidentally click to leave to a different page, not realizing that their data hasn’t been saved. This is pretty common use-case. Now, you might think that you would put that in the beforeDestroy hook. But that’s not really what beforeDestroy is for. That’s not it’s role. If you remember, the role of these two is really just to provide a way of cleaning up any processes. If you want to try to catch the user before they leave, the best and the recommended function to use is what is called the beforeRouteLeave function, it takes the same to, from, and next arguments.
And then from there what we can do is we can just ask the user a question. So I’ll say const answer = window.location or actually not location, this one’s window.confirm. And then, “Are you sure, your changes won’t be saved.”
And then from there all we’re gonna do window.cofirm gives us the ability to receive a Boolean value. So if they say okay, then it’s the same as storing true in answer, and if they say cancel, it’s the same as storing false. So if I say if the answer, which means if it’s true, then I want to allow them to go to whatever page it was they wanted to go to. Else, so if they hit cancel, then I wanna say next(false), which means that beforeRouteLeave is gonna say okay, it turns out that user didn’t wanna leave, and so do not allow them to leave. That’s why it’s called beforeRouteLeave.
So now … Oh, it looks like I have a typo. Oh, yeah, it’s a good reminder. Each one of these methods, and this is a case for all of Vue. Whenever you have these methods, they are objects. And so because at the end of the day export default is an object, it’s a set of key value pairs, then you have to make sure you list a comma after each one of those. But hitting save, that should fix it, and yes, we’re good to go.
So now we’re on the dashboard. Now if I click on home, you can see it has this little pop-up and it says, “Are you sure, your changes won’t be saved.” If I hit cancel, then nothing happens, we are kept on that page, and the user doesn’t lose their data. If I hit home, and hit okay, it allows me to be redirected. So that’s a way where you’re able to capture a user to make sure that they don’t do something like leave a page and lose data that they might’ve lost. And so that is a very helpful function.
So one last item I wanna leave you with. We’ve covered all of the methods, and we’ve discussed them, but the very first question that I had when I started going through these different elements was why do we need the beforeCreate and the created, the beforeMount and mounted? Why couldn’t we just use your created, mounted, and updated? And one thing I will say is, like I mentioned earlier, I really only use a few of these for every application I build. It’s very rare that I will use beforeMount, beforeCreate, or really even Created. The ones I use the most are gonna be mounted, beforeUpdate, updated, and then destroyed. And the task that I perform in each of those, and just as one side note, I do use these constantly but they’re not in lifecycle hooks, so I don’t count in the list, I use these in pretty much every single application a number of times. The beforeRouteEnter is the most common one I use, just because it allows me to have a guard in front of each component.
But going back to the lifecycle hooks, the mounted gives me pretty much all of the same access to data, and it gives me access to the lifecycle, or the point of the life of the component that beforeCreate/created, or beforeMount gives me.
So that’s the reason why I really use mounted for anything such as calling an outside API, storing the data, and then having it render on the page. That’s typically what I use mounted for. Occasionally I will use that inside of created, but most of the time I’m using that inside of mounted.
beforeUpdate is helpful for checking for data validation issues. So that’s what I use it for. So if you have a form with a number of validations and you do not want the user to be able to submit it and update the component without running through those validations, beforeUpdate is helpful through that.
Updated is helpful for updating the page after a change has occurred. So say the user hits save, they submitted some data, then updated allows me to capture that and then update the page automatically. And then like we talked about, the destroy items, and I typically just use destroyed, that’s usually where I am destroying things such as timers, or web sockets or anything like that.
So I know that was a longer guide, I really wanted to give you a single point of reference that you could look back at in the future, because this is something that I even have to look at quite often when I’m building out Vue apps, is seeing the full list of each one of these lifecycle hooks, and when they’re called. And so I wanted to give you a single guide that you could point to and say, “Okay, yeah, this is a full list of items, this is their syntax, their name, this is how they’re called, and this is how they work with components.”
So great job if you went through that, you should now have a good idea of how the lifecycle hook process works inside of Vue.js.