It is a no-go to manipulate the DOM in Vue.js directly:
<template>
<input id="myInput" />
</template>
<script setup>
onMounted(() => {
document.getElementById('myInput').focus()
})
</script>
Instead, you want to make use of refs:
<template>
<input ref="input" />
</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.
Let's take a look at the above example using a template ref:
<template>
<input ref="myInput" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
// We declare a ref to hold the element reference. The name must match the template ref value.
const myInput = ref(null)
onMounted(() => {
myInput.value.focus()
})
</script>
If you are trying to watch for changes of a template ref, make sure to check if the ref has a null value:
<template>
<input ref="myInput" />
</template>
<script setup>
import { ref, watchEffect } from 'vue'
const myInput = ref(null)
watchEffect(() => {
if (myInput.value) {
myInput.value.focus()
} else {
// not mounted yet, or the element was unmounted (e.g., by v-if)
}
})
</script>
If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter :
