SyntaxStudy
Sign Up
Vue.js onMounted and Template Refs
Vue.js Beginner 1 min read

onMounted and Template Refs

`onMounted` is the go-to hook for any work that requires a real DOM node: initialising a canvas, setting up a third-party map or chart library, measuring an element's dimensions, or triggering an animation. Before `onMounted` fires the template has not yet been inserted into the document, so accessing DOM elements there would yield `null`. Template refs give you a reactive handle on a specific DOM element or child component instance. Declare `const myEl = ref(null)` and attach it to an element with `ref="myEl"`. Inside `onMounted` (or any later hook) `myEl.value` holds the raw DOM node. For components, `myEl.value` is the component's public instance — or the object exposed via `defineExpose`. When a template ref is placed inside `v-for`, `myEl.value` becomes an array populated with all matched elements after the component mounts. Be aware that the array is not guaranteed to be in the same order as the source array, so use an explicit `:ref` callback if order matters.
Example
<template>
  <canvas ref="canvasEl" width="400" height="200"></canvas>
  <input  ref="inputEl"  placeholder="Auto-focused" />

  <!-- Child component ref -->
  <ChildForm ref="childRef" />

  <ul>
    <!-- Template ref in v-for -->
    <li v-for="item in items" :key="item.id" ref="listItems">
      {{ item.name }}
    </li>
  </ul>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import ChildForm from './ChildForm.vue';

const canvasEl  = ref(null);
const inputEl   = ref(null);
const childRef  = ref(null);
const listItems = ref([]);

const items = ref([
  { id: 1, name: 'Alpha' },
  { id: 2, name: 'Beta'  },
]);

onMounted(() => {
  // DOM element
  inputEl.value.focus();

  // Canvas 2D drawing
  const ctx = canvasEl.value.getContext('2d');
  ctx.fillStyle = 'royalblue';
  ctx.fillRect(20, 20, 360, 160);

  // Access exposed child method
  childRef.value?.reset();

  // Array ref from v-for
  console.log('List items:', listItems.value.map(el => el.textContent));
});
</script>