Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Lifecycle hooks

Every component goes through stages: creation, rendering onto the page (mounting), updates and removal (unmounting). Lifecycle hooks are functions through which you ask Vue to run code at a given stage, for example to start a timer when the component appears and stop it when the component disappears.

The onMounted hook

onMounted is called when the component's elements are already in the DOM:

<!-- src/components/TodoHeader.vue -->
<script setup>
import { onMounted } from 'vue'
 
console.log('setup: the component is being created')
 
onMounted(() => {
  console.log('mounted: the component is on the page')
})
</script>
 
<template>
  <h1>My tasks</h1>
</template>

The browser console shows two lines in this order: setup first, then mounted. Top-level <script setup> code runs before rendering, so there are no DOM elements there yet.

Main hooks

HookWhen it is calledWhat for
onMountedThe component is on the pageDOM work, loading data, subscriptions
onUpdatedAfter a re-render caused by data changesRarely: reading DOM sizes
onBeforeUnmountBefore removalSave something while the DOM still exists
onUnmountedThe component is removedStop timers, remove listeners

All hooks are imported from vue and called synchronously in <script setup>.

A timer with cleanup

A clock in the task list header is an example that needs two hooks:

<!-- src/components/TodoClock.vue -->
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
 
const time = ref(new Date().toLocaleTimeString())
let timerId
 
onMounted(() => {
  timerId = setInterval(() => {
    time.value = new Date().toLocaleTimeString()
  }, 1000)
})
 
onUnmounted(() => {
  clearInterval(timerId)
})
</script>
 
<template>
  <p>The time is {{ time }}</p>
</template>

Use the component in App.vue with the line <TodoClock v-if="showClock" /> — the clock ticks every second. When showClock becomes false, the component is removed and onUnmounted stops the timer.

Listeners on window

Listeners attached to window or document are removed the same way:

<script setup>
import { onMounted, onUnmounted } from 'vue'
 
function onKey(event) {
  if (event.key === 'Escape') console.log('Close')
}
 
onMounted(() => window.addEventListener('keydown', onKey))
onUnmounted(() => window.removeEventListener('keydown', onKey))
</script>

While the component is on the page, pressing Escape prints "Close" to the console.

Common mistake

Not stopping a timer or removing a listener in onUnmounted. The component leaves the page, but setInterval keeps running. If the component is shown and hidden several times, the timers pile up: the page slows down and the console fills with repeated messages. Whatever you start in onMounted, stop in onUnmounted.

Thanks for reading!

Donate to the site — we work hard for you.