As soon as the page loads, you want a certain function to be called.
Maybe you're fetching data, or you're initializing something.
How do we do this in Vue 3 with the Composition API?
You can just call the method directly from the setup
function:
<script setup>const initialize = () => {// ...};initialize();</script>
If you need to use the DOM in your initialize
function, you'll want to use the onMounted
lifecycle hook so that you can run code as soon as your component is mounted to the DOM:
import { onMounted } from 'vue';const initialize = () => {// ...};onMounted(() => initialize());
If you’re not using the Composition API, you’ll instead use the created
or mounted
hooks, which work exactly the same as the above solutions, just with a slightly different syntax:
export default {created() {// 1. Before the DOM has been set upthis.initialize();},mounted() {// 2. The DOM is ready to go nowthis.initialize();},methods: {initialize() {// ...},},};
But how, exactly, do these lifecycle hooks work?
This article will explain a few things:
onMounted
over running code in your setup
functionmounted
hook over the created
hook in the Options APIIn order to call a function as soon as our Vue component has loaded, we'll first need to get familiar with Vue's lifecycle hooks.
Earlier I said that the created
hook doesn't have access to the DOM.
Let me explain why that is.
Vue first creates the component, and then it mounts the component to the DOM. We can only access the DOM after the component has been mounted. This is done using the mounted
hook.
You can prove this to yourself by putting the following into your component:
created() {console.log(this.$el);},mounted() {console.log(this.$el);}
What was logged out?
You should have gotten undefined
, followed by a DOM element.
The DOM element for our component is set to this.$el
, but it doesn't exist yet in the created
hook.
However, it does exist in our mounted
hook, because Vue has already done the work of adding it to the DOM by the time it is called.
All Vue components have a series of stages — or lifecycles — that they go through.
As your app is run, your component will be:
First, the component is created.
Here, everything — including reactive data
, computed props, and watchers — are setup and intialized.
Second, the component is mounted to the DOM.
This involves creating the actual DOM nodes and inserting your component into the page.
Third, your component is updated as reactive data changes. Vue will re-render your component many times, in order to keep everything on the page up-to-date.
Lastly, when the component is no longer needed, it is destroyed.
Any event listeners are cleaned up, DOM nodes are removed from the page, and any memory it was using is now released.
That's not all.
Vue let's us hook into these lifecycles. This lets us run code when the component is created, mounted, updated, or destroyed! Plus a few other lifecycle hooks added in for convenience.
Here’s the full list:
onMounted
onUpdated
onUnmounted
onBeforeMount
onBeforeUpdate
onBeforeUnmount
onErrorCaptured
onRenderTracked
onRenderTriggered
onActivated
onDeactived
onServerPrefetch
There are a lot of them, but most of the time you’ll only need to use onMounted
, and sometimes onUnmounted
or onUpdated
.
There is so much more to talk about when it comes to lifecycle methods. I would suggest that you check out the docs to learn even more.
Using lifecycle hooks with the Composition API is as simple as importing them and passing in a function that will be run at the appropriate time:
import { onUpdated } from 'vue';onUpdated(() => console.log('Updated!'));
You may have noticed that many of these lifecycle hooks also come with a version prefixed with onBefore*
. These are, as you’d expect, run before the component lifecycle event. This can be very helpful if you need to do something immediately before the component is mounted or updated, for example.
Using lifecycle hooks with the Options API is very similar, but has some nuance we need to go into.
Lifecycle hooks work almost exactly the same in the Options API as they do in the Composition API, but we just have a different syntax to define them.
The only exception is that we need an extra created
hook. The setup
function in the Composition API is run as soon as the component is created, but since we don’t have that method in the Options API we need this extra hook.
But unlike with the Composition API, instead of defaulting to using the created
or setup
function for initialization code, I’d recommend the mounted
hook instead.
Let me explain why.
In nearly all cases, the mounted
hook is the right one for this job.
In fact, I almost always use this one. I only switch to a different hook if for some reason the mounted
hook doesn't work for what I am trying to do.
The reason is this:
In the mounted
hook, everything about the component has been initialized properly.
Reactive data is set up, watchers are running, and computed props are all hooked up.
Most importantly though, Vue has setup everything in the DOM. This means that you can safely do whatever you need to do in this lifecycle hook.
There can often be some confusion around the differences between the created
and mounted
hooks in the Options API.
As we saw earlier, the created
hook is run before the mounted
hook is run. The only thing missing is the DOM. Since we don't have access to our DOM element, we should use created
for anything that doesn't need the DOM element.
Oftentimes it is used to fetch data:
export default {data() {cars: {},},created() {fetch('/cars').then(cars => {this.cars = cars;});}};
The advantage of using created
instead of mounted
is that created
will be called a little sooner. This means you'll get your data just a tiny bit faster, although this difference is often negligible.