Let's assume that you have a conditional rendered input in Vue:
vue<template> <input v-if = "hamburger">Do you want ketchup?</input> <button @click = "setBurger">I want a hamburger</button> </template> <script> export default{ data(){ return{ hamburger: false } }, methods:{ setBurger(){ this.hamburger = true } } } </script>
Suppose that you want to focus the input just after clicking on the button.
The first option is modifying the DOM, for example, by getting the input element using JavaScript and using the focus()
function.
Example:
vue<template> <input v-if = "hamburger" id = "input">Do you want ketchup?</input> <button @click = "setBurger">I want a hamburger</button> </template> <script> export default{ data(){ return{ hamburger: false } }, methods:{ setBurger(){ this.hamburger = true // ❌ This won't work document.getElementById('input').focus() } } } </script>
The problem with this option is that you don't let time to Vue for rerendering the input, so you'll get an error (input isn't found). You could solve it by waiting for a few milliseconds:
vue<template> <input v-if = "hamburger" id = "input">Do you want ketchup?</input> <button @click = "setBurger">I want a hamburger</button> </template> <script> export default{ data(){ return{ hamburger: false } }, methods:{ setBurger(){ this.hamburger = true // ✅ This will work but it's not nice to manipulate the DOM setTimeout(() => document.getElementById('input').focus(), 50) } } } </script>
ref
and nextTick()
In Vue, you can use the ref
attribute instead of using an id
. To guarantee that the component is rerendered before focusing, instead of waiting for a random timeout, you can use the nextTick()
function:
vue<template> <input v-if = "hamburger" ref = "input">Do you want ketchup?</input> <button @click = "setBurger">I want a hamburger</button> </template> <script> import { nextTick } from vue export default{ data(){ return{ hamburger: false } }, methods:{ async setBurger(){ this.hamburger = true // ✅ This will work and you don't manipulate the DOM await nextTick() this.$refs.input.focus() } } } </script>
Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.