Setting focus of an input element in vue.js

Setting focus inside a child element

(for those of you that struggled for hours like me)

Parent:

<template>
  <div @click="$refs.theComponent.$refs.theInput.focus()">
    <custom-input ref="theComponent"/>
  </div>
</template>

Child (CustomInput.vue):

<template>
  <input ref="theInput"/>
</template>

Another solution using Vue 2.x and ref.

You can use the ref/$refs attribute to target your input and focus it.

In the example a simple method is used which can target the inputs using the ref attribute supplied to the inputs. Then access the $refs property on your instance to get a reference to the DOM element.

<script>
export default {
    // ...
  mounted: function () {
    this.focusInput('nameInput');
  },
  methods: {
    // This is the method that focuses the element
    focusInput: function ( inputRef ) {
      // $refs is an object that holds the DOM references to your inputs
      this.$refs[inputRef].focus();
    },

    search: function (event) {
      this.focusInput('domainInput');
    },
  }
}
</script>
<template>
  <form method="post" action="" v-on:submit.prevent="search">
    <input type="text" placeholder="Person name" required v-model="name" ref="nameInput" />
    <input type="text" placeholder="Company" required v-model="company" ref="domainInput" />
    <input type="submit" value="Search" class="btn show-m" />
  </form>
</template>

This solution is best for a one off situation or for a reusable component. For a more global approach the directive is the way to go.


There are a couple of issues.

First of all, v-els are defined like this:

<input v-el:input-element/>

That'll turn the variable to a camelCase in the code. You can read up more on this weird functionality here.

Other than that, you should be able to access the variable through this.$els.inputElement. Mind you, it will only appear in the component that you're defining that element (or the main app itself, if you defined it there).

Secondly, the automatic focusing does not seem to be working on Firefox (43.0.4), at least on my machine. Everything works great on Chrome, and focuses as expected.


In vue 2.x you can solve it with a directive.

Vue.directive('focus', {
    inserted: function (el) {
        el.focus()
    }
})

Then you can use v-focus attribute on inputs and other elements:

<input v-focus>