Every now and then you'll need to programmatically focus on an input (or other element).
This is often needed for accessibility, or to make the app more convenient to use.
All browsers have a built-in method that let us focus on a specific element. But we need to get a hold of that element first.
In vanilla Javascript you would grab your element using something like this:
<form><input id="email" /></form>
const input = document.getElementById('email');
But Vue 3 gives us a better way by using refs.
Let's see how this works in both the Composition API and the Options API.
First, we create a regular old ref
:
<script setup>import { ref } from 'vue';const email = ref(null);</script>
Then, we hook that ref up to our element by using the special ref
attribute:
<template><input ref="email" /></template>
Now, we just need to call the focus
method on the element in order to focus on it:
<script setup>import { ref } from 'vue';const email = ref(null);const focusInput = () => {if (email.value) {email.value.focus();}};</script>
The email
ref is a special kind of ref called a template ref, since it's linked to an element in our template.
If you're using the Options API, it would look like this:
<template><input ref="email" /></template>
const input = this.$refs.email;
Here we are using the special $refs
object instead of creating ref
variables.
Once we have our element, we can call focus
on it:
<template><input ref="email" /></template>
export default {methods: {focusInput() {this.$refs.email.focus();}}}
But what if you want to focus immediately when the component loads?
To do this, you'll want to call the focus method as soon as the component loads.
We'll need to make sure the element exists first, so we'll use the onMounted
lifecycle hook:
<script setup>import { ref, onMounted } from 'vue';const email = ref(null);const focusInput = () => {if (email.value) {email.value.focus();}};onMounted(focusInput);</script>
When using the Options API, this means we'll place the call in our mounted
lifecycle hook:
<template><CustomInput ref="email" /></template>
import CustomInput from './CustomInput.vue';export default {components: {CustomInput,},mounted() {this.focusInput();},methods: {focusInput() {this.$refs.email.$el.focus();}}}