To set focus on an input in Vue:
- Set a ref on the
input
element. - Access the new ref from the
$refs
property of the Vue instance. - Call the
focus()
method on the ref element object.
Set focus on input on button click
For example:
App.js
<template>
<div id="app">
<input
ref="name"
placeholder="Name"
/>{{ ' ' }}
<button @click="focusInput">Focus</button>
</div>
</template>
<script>
export default {
methods: {
focusInput() {
this.$refs.name.focus();
},
},
};
</script>
First, we create a new Vue instance ref by setting the input
ref
prop to a value (name
).
<input
ref="name"
placeholder="Name"
/>
After doing this, we are able to access the $refs
property of the Vue instance to access the object that represents the input element. We then call the focus()
method on this object to set focus on the input.
this.$refs.name.focus();
We set the focusInput()
method as a handler for the click
event of the Focus
button. So when the button is clicked, focusInput()
is called and the input
gains focus.
<button @click="focusInput">Focus</button>
Set focus on custom input component
Custom input components are useful for abstracting logic built around an input
element and for reusing an input
element styled in a particular way.
For custom components, calling focus()
on its ref object will cause an error. For it to work, we’ll need to add a focus()
method to the custom component that calls the focus()
method of its root input
element.
For example:
components/CustomInput.vue
<template>
<input
placeholder="Name"
class="custom-input"
ref="input"
/>
</template>
<script>
export default {
methods: {
// 👇 Create custom "focus" method
focus() {
this.$refs.input.focus();
},
},
};
</script>
<style scoped>
.custom-input {
font-family: 'Segoe UI';
font-weight: bold;
font-size: 16px;
color: blue;
height: 30px;
width: 200px;
}
</style>
App.js
<template>
<div id="app">
<custom-input ref="name"></custom-input>
<br />
<br />
<button @click="focusInput">Focus</button>
</div>
</template>
<script>
import CustomInput from './components/CustomInput.vue';
export default {
methods: {
focusInput() {
// 👇 call custom "focus" method
this.$refs.name.focus();
},
},
components: { CustomInput },
};
</script>
Now we can set focus on the custom input component when the button is clicked.
Set focus on input after page load
To give the input focus immediately after the page loads, we can call the focus()
method from the mounted
lifecycle hook of the Vue instance with the input ref. The mounted
method is called after a component is added to the DOM, which happens when a page is loading.
For example:
App.js
<template>
<div id="app">
<input
ref="name"
placeholder="Name"
/>
</div>
</template>
<script>
export default {
mounted() {
this.focusInput();
},
methods: {
focusInput() {
this.$refs.name.focus();
},
},
};
</script>
Set focus on input after re-render
There are scenarios where we’ll need to wait for the DOM to be updated before calling focus()
to give the input element focus.
For example, we might be using a boolean variable to determine whether an input element should be present in the DOM or not.
Because Vue batches state updates, the input element might not be added to the DOM immediately, and we won’t be able to access its ref right away.
We can use the nextTick()
instance method to ensure that the DOM has been updated to include the input after modifying the boolean variable before calling focus()
.
<template>
<div id="app">
<!-- 👇 conditional rendering with "v-if" directive -->
<input
v-if="showInput"
ref="name"
placeholder="Name"
/>
<br /><br />
<button @click="focusInput">Show and focus</button>
</div>
</template>
<script>
export default {
data() {
return {
showInput: false,
};
},
methods: {
focusInput() {
// 👇 Set boolean variable to show input
this.showInput = true;
this.$nextTick(() => {
// This callback will only be called after the
// DOM has been updated
this.$refs.name.focus();
});
},
},
};
</script>
Set focus on next input after Enter press
Let’s say we have multiple input elements that need to be filled on the page. We could improve the UX by focusing on the succeeding text input when the user presses the Enter key to signify that they are done with filling in one input.
We do this by assigning a listener to the keypress
event on the first input. Because of the enter
event modifier, the event listener is only called when a key is pressed and the key is Enter.
We create a ref for the second input, and in the keypress.enter
event listener we call the focus()
method on the ref object to set focus on the second input.
<template>
<div id="app">
<form>
<input
placeholder="1st name"
@keypress.enter="focusName2"
/>
<br /><br />
<input
ref="name2"
placeholder="2nd name"
/>
</form>
</div>
</template>
<script>
export default {
methods: {
focusName2() {
this.$refs.name2.focus();
},
},
};
</script>
Every Crazy Thing JavaScript Does
A captivating guide to the subtle caveats and lesser-known parts of JavaScript.