Join my Vue.js course while it's free πŸ‘€

Get an element by its ID using Vue.js

April 2, 2022  ‐ 3Β min read

With plain JavaScript you find yourself regularly jumping into the DOM, to get the attributes of an element, add event handlers and other operations. For these actions there is a good chance you would have used the good old JavaScript function document.getElementById, which would hand you back the HTML element you wish to manipulate.

The Vue framework, luckily, hides most of the DOM operations behind a friendly API. Instead of needing to call addEventListener("click", function () {...}, you can bind an event directly to an HTML element using v-on:click=”...” or its shorthand notation @click=”...”. Or when you need to access a value of a form input, you can easily set up a data property in your Vue component and bind it to the form input using v-model.

However, once in a while I do need to access DOM elements directly. When I need to get the dimensions in pixels of an element for example. For such a use-case you can fall back on using the native JavaScript document.getElementById function again. But Vue has something built-in for such a use-case as well, namely template refs.

Defining template refs

A template ref, short for reference I assume, allows you to easily access an HTML element in your Vue code. A template ref is created by adding the special ref=”...” attribute to an element in your template.

<template>
  <img ref="picture" src="example.png" />
</template>

Next, once the component is mounted we can access our img element using the picture reference. But how to do so depends on whether using the options API or the new composition API which was introduced in Vue 3.

Accessing refs using the options API

In the options API your template references are accessible as a property of this.$refs. So in our example we can example we can access the img element via this.$refs.picture. Do keep in mind that this element only exists after the component in mounted, so try to access the picture ref in the created lifecycle hook will return null instead of the HTML element.

<template>
  <img ref="picture" src="example.png" />
</template>

<script>
  export default {
    mounted() {
      const height = this.$refs.picture.clientHeight;
    },
  };
</script>

Accessing refs using the composition API

The composition API obviously allows for accessing template refs as well. However, you need to pay a bit more attention to detail here. In your setup script, or setup() function if you prefer that, you need to define a variable named the same as your ref and assign it to ref(null).

After the component is mounted, you can access the ref using the variable you defined. Where this differs from the options API is that your HTML element lives under <ref>.value instead of directly under <ref>. In our example the HTML element itself can be accessed as picture.value.

<template>
  <img ref="picture" src="example.png" />
</template>

<script setup>
  import { ref, onMounted } from "vue";

  // IMPORTANT: Variable should be named the same as the ref.
  const picture = ref(null);

  onMounted(() => {
    const height = picture.value.clientHeight;
  });
</script>