Javascript is required
ยท
1 min read

Vue Tip: Avoid Directly DOM Manipulation

Vue Tip: Avoid Directly DOM Manipulation Image

It is a no-go to manipulate the DOM in Vue.js directly:

1<template>
2  <input id="myInput" />
3</template>
4
5<script setup>
6onMounted(() => {
7  document.getElementById('myInput').focus()
8})
9</script>

Instead, you want to make use of refs:

1<template>
2  <input ref="input" />
3</template>

ref is a special attribute that allows us to obtain a direct reference to a specific DOM element or child component instance after it's mounted.

Warning

Note that you can only access the ref after the component is mounted because the element doesn't exist until after the first render.

Let's take a look at the above example using a template ref:

1<template>
2  <input ref="myInput" />
3</template>
4
5<script setup>
6import { ref, onMounted } from 'vue'
7
8// We declare a ref to hold the element reference. The name must match the template ref value.
9const myInput = ref(null)
10
11onMounted(() => {
12  myInput.value.focus()
13})
14</script>

If you are trying to watch for changes of a template ref, make sure to check if the ref has a null value:

1<template>
2  <input ref="myInput" />
3</template>
4
5<script setup>
6import { ref, watchEffect } from 'vue'
7
8const myInput = ref(null)
9
10watchEffect(() => {
11  if (myInput.value) {
12    myInput.value.focus()
13  } else {
14    // not mounted yet, or the element was unmounted (e.g., by v-if)
15  }
16})
17</script>

If you liked this Vue tip, follow me on X to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter:

I will never share any of your personal data. You can unsubscribe at any time.